<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222"><meta name="generator" content="Hexo 6.1.0">


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.css">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/pace/1.2.4/themes/green/pace-theme-minimal.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/pace/1.2.4/pace.min.js" integrity="sha256-gqd7YTjg/BtfqWSwsJOvndl0Bxc8gFImLEkXQT8+qj0=" crossorigin="anonymous"></script>

<script class="next-config" data-name="main" type="application/json">{"hostname":"liukairui.me","root":"/","images":"/images","scheme":"Muse","darkmode":false,"version":"8.10.1","exturl":false,"sidebar":{"position":"left","display":"hide","padding":18,"offset":12},"copycode":true,"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":true,"pangu":true,"comments":{"style":"tabs","active":"valine","storage":true,"lazyload":false,"nav":null,"activeClass":"valine"},"stickytabs":false,"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"},"path":"/search.xml","localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false}}</script><script src="/js/config.js"></script>

    <meta name="description" content="Ajax与Axios学习与初步源码分析笔记,包含了使用XHR完成Ajax请求,jQuery的Ajax请求,ES新增的ftech,Axios的使用与实现,主讲:尚硅谷李强,视频来自B站:BV1wr4y1K7tq">
<meta property="og:type" content="article">
<meta property="og:title" content="Ajax与Axios的使用与关键源码笔记">
<meta property="og:url" content="http://liukairui.me/article/Ajax%E4%B8%8EAxios%E7%9A%84%E4%BD%BF%E7%94%A8%E4%B8%8E%E5%85%B3%E9%94%AE%E6%BA%90%E7%A0%81%E7%AC%94%E8%AE%B0/">
<meta property="og:site_name" content="LiuKairui Website">
<meta property="og:description" content="Ajax与Axios学习与初步源码分析笔记,包含了使用XHR完成Ajax请求,jQuery的Ajax请求,ES新增的ftech,Axios的使用与实现,主讲:尚硅谷李强,视频来自B站:BV1wr4y1K7tq">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2021-06-15T16:22:52.000Z">
<meta property="article:modified_time" content="2021-10-18T06:44:13.594Z">
<meta property="article:author" content="Liu Kairui">
<meta property="article:tag" content="前端">
<meta property="article:tag" content="笔记">
<meta property="article:tag" content="JavaScript">
<meta property="article:tag" content="Ajax">
<meta property="article:tag" content="Axios">
<meta name="twitter:card" content="summary">


<link rel="canonical" href="http://liukairui.me/article/Ajax%E4%B8%8EAxios%E7%9A%84%E4%BD%BF%E7%94%A8%E4%B8%8E%E5%85%B3%E9%94%AE%E6%BA%90%E7%A0%81%E7%AC%94%E8%AE%B0/">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"zh-CN","comments":true,"permalink":"http://liukairui.me/article/Ajax%E4%B8%8EAxios%E7%9A%84%E4%BD%BF%E7%94%A8%E4%B8%8E%E5%85%B3%E9%94%AE%E6%BA%90%E7%A0%81%E7%AC%94%E8%AE%B0/","path":"article/Ajax与Axios的使用与关键源码笔记/","title":"Ajax与Axios的使用与关键源码笔记"}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>Ajax与Axios的使用与关键源码笔记 | LiuKairui Website</title>
  

  <script src="/js/third-party/analytics/baidu-analytics.js"></script>
  <script async src="https://hm.baidu.com/hm.js?ea07bceb8f5fa721da2ebf01833faa32"></script>



<div class="nindexBK">
<div class="nindexBKC"></div>
<div class="nindex">
  <h1>Hey👋</h1>
  <p style="font-weight: 500; font-size: 2.2em">欢迎访问Liu Kairui的个人站.</p>
  <p>
      我是一个来自重庆的在校大学生, 偏爱于前端技术<!--与OS设计-->, 偶尔使用 JS / Go 进行轻量项目开发, 欢迎访问我的
      <a href="https://github.com/KairuiLiu" target="_blank"><i class="fab fa-github-alt"></i> GitHub</a> .
  </p>
  <p>
      这个网站主要用来存储学习 / 瞎搞的笔记, 同时提供了邮件、图床等服务. 对于一些自认为有趣的<a href="javascript:;" id="myProj">项目</a>, 我也会将项目介绍, 文档, 甚至是设计指南发布在这里.
  </p>
  <ul>
    <li><p><a href="/artrank/" target="_blank">ArtRank</a>: 基于Node.JS的PageRank文献管理推荐系统</p></li>
    <li><p><a href="/gooj/" target="_blank">GoOJ</a>: 基于Golang的高校在线评测系统</p></li>
    <li><p><a href="/projects/" target="_blank">更多 <i class="fas fa-angle-right"></i></a></p></li>

  </ul>
  <p>
      可以在这些平台找到我: 
      <a href="https://www.zhihu.com/people/liu-kai-rui-18" target="_blank">知乎</a>,
      <a href="https://space.bilibili.com/33238144" target="_blank">bilibili</a>
      和
      <a href="https://www.coolapk.com/u/805314?from=qr" target="_blank">酷安</a>.
  </p>

  <p>
      下滑即可进入博客 <i class="fas fa-arrow-down"></i>
  </p>
</div>
</div>  

 
<script>
  var OriginTitile = document.title;
  var titleTime;
  document.addEventListener("visibilitychange", function() {
    if (document.hidden) {
      document.title = "谢谢离开 | " + OriginTitile;
      clearTimeout(titleTime);
    } else {
      document.title = "欢迎归来 | " + OriginTitile;
      titleTime = setTimeout(function() {
        document.title = OriginTitile;
      }, 2000);
    }
  });
</script>


<script>
  function checkIndex(){
    let nindexItems = [[".nindexBK","display","block","none"],[".headband","display","none","block"],["div.toggle.sidebar-toggle","visibility","hidden","visible"]]; // ,["button.darkmode-toggle","visibility","hidden","visible"]];
    let isIndex = new RegExp("^(\/){0,1}(index){0,1}(\.html){0,1}(/)*$").test(location.pathname);
    let backCanvas = document.querySelector(".nindexBK");
    nindexItems.dispShift = function (stat){this.forEach((e) => {try{document.querySelector(e[0]).style[e[1]]=e[2+stat];}catch{}})}
    if(isIndex){
      nindexItems.dispShift(0);
      window.onscroll=function(){
        if(document.documentElement.scrollTop>backCanvas.offsetHeight*1.05){
          nindexItems.dispShift(1);window.onscroll=null;
        }
      }
      document.querySelector("#myProj").onclick=()=>{
        let projlist = document.querySelector(".nindex>ul");
        projlist.className.indexOf("ulactive")==-1?projlist.classList.add("ulactive"):projlist.classList.remove("ulactive")
      }
    }else nindexItems.dispShift(1);
  }
  checkIndex();
</script>

<!--<script src="https://sdk.jinrishici.com/v2/browser/jinrishici.js" charset="utf-8"></script>-->

  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
<link rel="alternate" href="/atom.xml" title="LiuKairui Website" type="application/atom+xml">
<style>.darkmode--activated{--body-bg-color:#282828;--content-bg-color:#333;--card-bg-color:#555;--text-color:#ccc;--blockquote-color:#bbb;--link-color:#ccc;--link-hover-color:#eee;--brand-color:#ddd;--brand-hover-color:#ddd;--table-row-odd-bg-color:#282828;--table-row-hover-bg-color:#363636;--menu-item-bg-color:#555;--btn-default-bg:#222;--btn-default-color:#ccc;--btn-default-border-color:#555;--btn-default-hover-bg:#666;--btn-default-hover-color:#ccc;--btn-default-hover-border-color:#666;--highlight-background:#282b2e;--highlight-foreground:#a9b7c6;--highlight-gutter-background:#34393d;--highlight-gutter-foreground:#9ca9b6}.darkmode--activated img{opacity:.75}.darkmode--activated img:hover{opacity:.9}.darkmode--activated code{color:#69dbdc;background:0 0}button.darkmode-toggle{z-index:9999}.darkmode-ignore,img{display:flex!important}</style></head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <p class="site-title">LiuKairui Website</p>
      <i class="logo-line"></i>
    </a>
      <p class="site-subtitle" itemprop="description">要有信仰</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu">
        <li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a></li>
        <li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a></li>
        <li class="menu-item menu-item-tags"><a href="/tags/" rel="section"><i class="fas fa-hashtag fa-fw"></i>标签</a></li>
        <li class="menu-item menu-item-收藏夹"><a href="/favorites/" rel="section"><i class="fab fa-gratipay fa-fw"></i>收藏夹</a></li>
        <li class="menu-item menu-item-留言板"><a href="/messageBoard/" rel="section"><i class="fab fa-facebook-messenger fa-fw"></i>留言板</a></li>
        <li class="menu-item menu-item-项目"><a href="/projects/" rel="section"><i class="fa fa-satellite fa-fw"></i>项目</a></li>
        <li class="menu-item menu-item-图床"><a href="http://img.liukairui.me/" rel="noopener" target="_blank"><i class="fa fa-bed fa-fw"></i>图床</a></li>
        <li class="menu-item menu-item-云ide"><a href="http://vsc.liukairui.me/" rel="noopener" target="_blank"><i class="fas fa-code fa-fw"></i>云IDE</a></li>
        <li class="menu-item menu-item-about"><a href="/about/" rel="section"><i class="fa fa-user fa-fw"></i>关于</a></li>
        <li class="menu-item menu-item-邮箱"><a href="http://mail.liukairui.me/mail" rel="noopener" target="_blank"><i class="fas fa-envelope-open-text fa-fw"></i>邮箱</a></li>
        <li class="menu-item menu-item-rss"><a href="/atom.xml" rel="section"><i class="fa fa-rss fa-fw"></i>RSS</a></li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup"><div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off" maxlength="80"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close" role="button">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div class="search-result-container no-result">
  <div class="search-result-icon">
    <i class="fa fa-spinner fa-pulse fa-5x"></i>
  </div>
</div>

    </div>
  </div>

</div>
        
  
  <div class="toggle sidebar-toggle" role="button">
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
  </div>

  <aside class="sidebar">

    <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
            <div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#ajax%E6%A6%82%E8%BF%B0"><span class="nav-number">1.</span> <span class="nav-text">Ajax概述</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%8E%9F%E7%94%9Fajax%E5%B0%9D%E8%AF%95"><span class="nav-number">2.</span> <span class="nav-text">原生Ajax尝试</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E8%AF%B7%E6%B1%82%E7%9A%84%E5%8F%91%E9%80%81%E4%B8%8E%E8%AF%B7%E6%B1%82%E5%A4%B4%E9%85%8D%E7%BD%AE"><span class="nav-number">2.1.</span> <span class="nav-text">请求的发送与请求头配置</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#json%E6%94%AF%E6%8C%81"><span class="nav-number">2.2.</span> <span class="nav-text">JSON支持</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#ie%E7%BC%93%E5%AD%98%E9%97%AE%E9%A2%98"><span class="nav-number">2.3.</span> <span class="nav-text">IE缓存问题</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E8%AF%B7%E6%B1%82%E7%9A%84%E5%8F%96%E6%B6%88%E4%B8%8E%E9%87%8D%E5%8F%91"><span class="nav-number">2.4.</span> <span class="nav-text">请求的取消与重发</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#jquery%E7%9A%84ajax"><span class="nav-number">3.</span> <span class="nav-text">jQuery的Ajax</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E4%BD%BF%E7%94%A8axios%E5%8F%91%E9%80%81ajax%E7%AE%80%E6%98%93"><span class="nav-number">4.</span> <span class="nav-text">使用Axios发送Ajax[简易]</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E4%BD%BF%E7%94%A8fetch%E5%8F%91%E9%80%81%E8%AF%B7%E6%B1%82"><span class="nav-number">5.</span> <span class="nav-text">使用fetch发送请求</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#ajax%E8%B7%A8%E5%9F%9F"><span class="nav-number">6.</span> <span class="nav-text">Ajax跨域</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#jsonp%E8%A7%A3%E5%86%B3%E8%B7%A8%E5%9F%9F%E9%97%AE%E9%A2%98"><span class="nav-number">6.1.</span> <span class="nav-text">JSONP解决跨域问题</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#cors%E8%A7%A3%E5%86%B3%E8%B7%A8%E5%9F%9F%E9%97%AE%E9%A2%98"><span class="nav-number">6.2.</span> <span class="nav-text">CORS解决跨域问题</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#axios%E7%9A%84%E7%90%86%E8%A7%A3%E4%B8%8E%E4%BD%BF%E7%94%A8"><span class="nav-number">7.</span> <span class="nav-text">Axios的理解与使用</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#json-server%E7%9A%84%E4%BD%BF%E7%94%A8"><span class="nav-number">7.1.</span> <span class="nav-text">JSON Server的使用</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#axios%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8"><span class="nav-number">7.2.</span> <span class="nav-text">Axios基本使用</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%8B%A6%E6%88%AA%E5%99%A8"><span class="nav-number">7.3.</span> <span class="nav-text">拦截器</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%8F%96%E6%B6%88%E8%AF%B7%E6%B1%82"><span class="nav-number">7.4.</span> <span class="nav-text">取消请求</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%9B%AE%E5%BD%95%E7%BB%93%E6%9E%84"><span class="nav-number">7.5.</span> <span class="nav-text">目录结构</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%AE%9E%E7%8E%B0axios%E4%BD%BF%E5%BE%97%E6%97%A2%E5%8F%AF%E4%BB%A5axios%E4%B9%9F%E5%8F%AF%E4%BB%A5axios.xx"><span class="nav-number">7.6.</span> <span class="nav-text">实现axios,使得既可以axios()也可以axios.xx()</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#axios%E7%B1%BB%E7%9A%84%E5%AE%9E%E7%8E%B0"><span class="nav-number">7.7.</span> <span class="nav-text">Axios类的实现</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%89%8B%E5%86%99%E4%B8%80%E4%B8%AA%E7%AE%80%E6%98%93%E7%89%88%E7%9A%84axios"><span class="nav-number">7.8.</span> <span class="nav-text">手写一个简易版的axios</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E8%AF%B7%E6%B1%82%E5%8F%91%E9%80%81%E5%87%BD%E6%95%B0"><span class="nav-number">7.9.</span> <span class="nav-text">请求发送函数</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E8%AF%B7%E6%B1%82%E5%8F%96%E6%B6%88%E5%87%BD%E6%95%B0"><span class="nav-number">7.10.</span> <span class="nav-text">请求取消函数</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%80%BB%E7%BB%93%E5%85%AB%E8%82%A1"><span class="nav-number">7.11.</span> <span class="nav-text">总结(八股)</span></a></li></ol></li></ol></div>
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author site-overview-item animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="Liu Kairui"
      src="/images/avatar.jpg">
  <p class="site-author-name" itemprop="name">Liu Kairui</p>
  <div class="site-description" itemprop="description">LiuKairui Persional Website</div>
</div>
<div class="site-state-wrap site-overview-item animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">45</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
          <a href="/categories/">
        <span class="site-state-item-count">24</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
          <a href="/tags/">
        <span class="site-state-item-count">53</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>
  <div class="links-of-author site-overview-item animated">
      <span class="links-of-author-item">
        <a href="https://github.com/KairuiLiu" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;KairuiLiu" rel="noopener" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
      </span>
      <span class="links-of-author-item">
        <a href="mailto:tclkr@live.com" title="E-Mail → mailto:tclkr@live.com" rel="noopener" target="_blank"><i class="fa fa-envelope fa-fw"></i>E-Mail</a>
      </span>
      <span class="links-of-author-item">
        <a href="https://qm.qq.com/cgi-bin/qm/qr?k=oaf3ToOlN17hr5sHV98bT8qxsNYGaw5L&noverify=0" title="QQ → https:&#x2F;&#x2F;qm.qq.com&#x2F;cgi-bin&#x2F;qm&#x2F;qr?k&#x3D;oaf3ToOlN17hr5sHV98bT8qxsNYGaw5L&amp;noverify&#x3D;0" rel="noopener" target="_blank"><i class="fab fa-qq fa-fw"></i>QQ</a>
      </span>
      <span class="links-of-author-item">
        <a href="/atom.xml" title="RSS → &#x2F;atom.xml"><i class="fa fa-rss fa-fw"></i>RSS</a>
      </span>
      <span class="links-of-author-item">
        <a href="https://liukairui.blog.csdn.net/" title="CSDN → https:&#x2F;&#x2F;liukairui.blog.csdn.net" rel="noopener" target="_blank"><i class="fab fa-cuttlefish fa-fw"></i>CSDN</a>
      </span>
      <span class="links-of-author-item">
        <a href="http://liukairui.cc/" title="国内站点 → http:&#x2F;&#x2F;liukairui.cc" rel="noopener" target="_blank"><i class="fa fa-globe fa-fw"></i>国内站点</a>
      </span>
  </div>
  <div class="cc-license site-overview-item animated" itemprop="license">
    <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh" class="cc-opacity" rel="noopener" target="_blank"><img src="https://cdnjs.cloudflare.com/ajax/libs/creativecommons-vocabulary/2020.11.3/assets/license_badges/small/by_nc_sa.svg" alt="Creative Commons"></a>
  </div>


  <div class="links-of-blogroll site-overview-item animated">
    <div class="links-of-blogroll-title"><i class="fa fa-link fa-fw"></i>
      友情链接
    </div>
    <ul class="links-of-blogroll-list">
        <li class="links-of-blogroll-item">
          <a href="https://paste.ubuntu.com/" title="https:&#x2F;&#x2F;paste.ubuntu.com&#x2F;" rel="noopener" target="_blank">Ubuntu Pastebin</a>
        </li>
        <li class="links-of-blogroll-item">
          <a href="https://send.firefox.com/" title="https:&#x2F;&#x2F;send.firefox.com&#x2F;" rel="noopener" target="_blank">Firefox Send</a>
        </li>
        <li class="links-of-blogroll-item">
          <a href="https://jkwzs.cn/" title="https:&#x2F;&#x2F;jkwzs.cn&#x2F;" rel="noopener" target="_blank">南花醉笔丶の个人博客</a>
        </li>
        <li class="links-of-blogroll-item">
          <a href="https://ywrby.cn/" title="https:&#x2F;&#x2F;ywrby.cn&#x2F;" rel="noopener" target="_blank">Ywrby个人博客</a>
        </li>
    </ul>
  </div>

        </div>
      </div>
    </div>
  </aside>
  <div class="sidebar-dimmer"></div>


    </header>

    
  <div class="back-to-top" role="button" aria-label="返回顶部">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>
  <div class="reading-progress-bar"></div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


    <div class="main-inner post posts-expand">


  


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://liukairui.me/article/Ajax%E4%B8%8EAxios%E7%9A%84%E4%BD%BF%E7%94%A8%E4%B8%8E%E5%85%B3%E9%94%AE%E6%BA%90%E7%A0%81%E7%AC%94%E8%AE%B0/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.jpg">
      <meta itemprop="name" content="Liu Kairui">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="LiuKairui Website">
      <meta itemprop="description" content="LiuKairui Persional Website">
    </span>
    
    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="Ajax与Axios的使用与关键源码笔记 | LiuKairui Website">
      <meta itemprop="description" content="Ajax与Axios学习与初步源码分析笔记,包含了使用XHR完成Ajax请求,jQuery的Ajax请求,ES新增的ftech,Axios的使用与实现,主讲:尚硅谷李强,视频来自B站:BV1wr4y1K7tq">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          Ajax与Axios的使用与关键源码笔记
        </h1>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-06-16 00:22:52" itemprop="dateCreated datePublished" datetime="2021-06-16T00:22:52+08:00">2021-06-16</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%89%8D%E7%AB%AF/" itemprop="url" rel="index"><span itemprop="name">前端</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%89%8D%E7%AB%AF/JS/" itemprop="url" rel="index"><span itemprop="name">JS</span></a>
        </span>
    </span>

  
    <span id="/article/Ajax%E4%B8%8EAxios%E7%9A%84%E4%BD%BF%E7%94%A8%E4%B8%8E%E5%85%B3%E9%94%AE%E6%BA%90%E7%A0%81%E7%AC%94%E8%AE%B0/" class="post-meta-item leancloud_visitors" data-flag-title="Ajax与Axios的使用与关键源码笔记" title="阅读次数">
      <span class="post-meta-item-icon">
        <i class="far fa-eye"></i>
      </span>
      <span class="post-meta-item-text">阅读次数：</span>
      <span class="leancloud-visitors-count"></span>
    </span>
  
  <span class="post-meta-item">
    
    <span class="post-meta-item-icon">
      <i class="far fa-comment"></i>
    </span>
    <span class="post-meta-item-text">Valine：</span>
  
    <a title="valine" href="/article/Ajax%E4%B8%8EAxios%E7%9A%84%E4%BD%BF%E7%94%A8%E4%B8%8E%E5%85%B3%E9%94%AE%E6%BA%90%E7%A0%81%E7%AC%94%E8%AE%B0/#valine-comments" itemprop="discussionUrl">
      <span class="post-comments-count valine-comment-count" data-xid="/article/Ajax%E4%B8%8EAxios%E7%9A%84%E4%BD%BF%E7%94%A8%E4%B8%8E%E5%85%B3%E9%94%AE%E6%BA%90%E7%A0%81%E7%AC%94%E8%AE%B0/" itemprop="commentCount"></span>
    </a>
  </span>
  
  

<script>
    CONFIG.hostname = location.hostname;
</script>
    <span class="post-meta-break"></span>
    <span class="post-meta-item" title="本文字数">
      <span class="post-meta-item-icon">
        <i class="far fa-file-word"></i>
      </span>
      <span class="post-meta-item-text">本文字数：</span>
      <span>41k</span>
    </span>
    <span class="post-meta-item" title="阅读时长">
      <span class="post-meta-item-icon">
        <i class="far fa-clock"></i>
      </span>
      <span class="post-meta-item-text">阅读时长 &asymp;</span>
      <span>37 分钟</span>
    </span>
</div>

            <div class="post-description">Ajax与Axios学习与初步源码分析笔记,包含了使用XHR完成Ajax请求,jQuery的Ajax请求,ES新增的ftech,Axios的使用与实现,主讲:尚硅谷李强,视频来自B站:BV1wr4y1K7tq</div>
        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
        <h2 id="ajax概述">Ajax概述</h2>
<p><strong>Ajax简介</strong>：Ajax(Async JavaScript and
XML)在网页<strong>不刷新</strong>的情况下向服务器发送请求，获取响应，实现懒加载的过程</p>
<p><strong>XML简介</strong>：XML与HTML类似，都是一种基于<strong>标签</strong>的<strong>标记</strong>语言</p>
<ul>
<li>HTML的标签都是预定义的，一般用来描述网页</li>
<li>XML没有预定义标签，标签名都是直接写来用的，一般用来存储数据，曾经的Ajax使用XML传输数据</li>
</ul>
<p><strong>AJAX的优缺点</strong></p>
<ul>
<li>无需刷新就可以与服务器发送接受请求</li>
<li>可以根据用户的事件动态更新页面内容</li>
<li>没有浏览历史(无法后退)</li>
<li>存在跨域问题(A网站向B网站发送内容)</li>
<li>对SEO优化不友好</li>
</ul>
<p><strong>HTTP协议(详见计算机网络)</strong><br />
规定了浏览器与万维网服务之间的通信，规定了请求与响应，此处主要了解请求与响应报文的格式与参数</p>
<ul>
<li>请求报文结构
<ul>
<li>请求行
<ul>
<li>请求类型: Get/Post/Put...</li>
<li>URL: /xxx?name=zhangsan&amp;passwd=lisi</li>
<li>HTTP协议版本: HTTP/1.1...</li>
</ul></li>
<li>请求头
<ul>
<li>Host: www.liukairui.cc</li>
<li>Cookie: username=admin</li>
<li>Content-type: text...</li>
<li>User-Agent: Chrome90</li>
</ul></li>
<li>空行</li>
<li>请求体
<ul>
<li>如果是GET请求，那么请求体是空的</li>
<li>如果是POST请求，那么请求体可以是非空的</li>
</ul></li>
</ul></li>
<li>响应报文结构
<ul>
<li>响应行
<ul>
<li>HTTP协议版本: HTTP/1.1...</li>
<li>响应状态码: 200...</li>
<li>响应状态字符串: OK</li>
</ul></li>
<li>响应头
<ul>
<li>Content-type: text...</li>
<li>Content-encoding: gzip</li>
<li>Content-length: 1024</li>
</ul></li>
<li>空行</li>
<li>响应体: 例如HTML内容</li>
</ul></li>
</ul>
<p><strong>Chrome查看报文</strong></p>
<ul>
<li>F12-Network-选中包</li>
<li>对于GET请求，可以看到
<ul>
<li>Header选项卡中有四个部分
<ul>
<li>General: 请求地址，请求方式，状态码，服务器IP，同源策略</li>
<li>Response Headers响应头</li>
<li>Request Headers请求头</li>
<li>Query String Paramenters将请求url的内容进行解析</li>
</ul></li>
<li>Response: 响应体</li>
<li>Preview: 预览响应体</li>
</ul></li>
<li>对于POST请求，可以看到
<ul>
<li>Header选项卡中有四个部分
<ul>
<li>General: 请求地址，请求方式，状态码，服务器IP，同源策略</li>
<li>Response Headers响应头</li>
<li>Request Headers请求头</li>
<li>Query String Parameters: 请求体</li>
</ul></li>
<li>Response: 响应体</li>
<li>Preview: 预览响应体</li>
</ul></li>
</ul>
<h2 id="原生ajax尝试">原生Ajax尝试</h2>
<p>Ajax技术可以理解为手动在JS中进行http请求，获取响应报文，根据响应报文修改文件，与之前不同的是，之前是浏览器向服务器发送请求，服务器发送响应，浏览器刷新页面。现在是JS进行请求，JS自己处理结果，我们需要的是一套可以进行Http请求的JSAPI</p>
<h3 id="请求的发送与请求头配置">请求的发送与请求头配置</h3>
<p><strong>GET部分</strong></p>
<ul>
<li>服务端配置<br />
服务端使用的是NodeJS,我们需要Express处理http请求，其他的都不需要
<pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">const</span> express <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">"express"</span><span class="token punctuation">)</span>
<span class="token keyword">var</span> app<span class="token operator">=</span><span class="token function">express</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

app<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">"/server"</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span>res</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    <span class="token comment">// 配置Ajax同源策略，允许跨域访问</span>
    res<span class="token punctuation">.</span><span class="token function">setHeader</span><span class="token punctuation">(</span><span class="token string">'Access-Control-Allow-Origin'</span><span class="token punctuation">,</span><span class="token string">'*'</span><span class="token punctuation">)</span>
    <span class="token comment">// 发回响应体</span>
    res<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token string">"Wow Ajax working..."</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

app<span class="token punctuation">.</span><span class="token function">listen</span><span class="token punctuation">(</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"work on"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span></code></pre>
Node代码实现了收到一个/server请求，发回数据，由于但是没有设置页面的路由，我们需要手动打开网页</li>
<li>HTML页面 <pre class="language-html" data-language="html"><code class="language-html"><span class="token doctype"><span class="token punctuation">&lt;!</span><span class="token doctype-tag">DOCTYPE</span> <span class="token name">html</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>en<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">charset</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>UTF-8<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span><span class="token punctuation">></span></span>发送AJAX<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>result<span class="token punctuation">"</span></span> <span class="token special-attr"><span class="token attr-name">style</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token value css language-css"><span class="token property">border</span><span class="token punctuation">:</span>solid<span class="token punctuation">;</span><span class="token property">width</span><span class="token punctuation">:</span> 200px<span class="token punctuation">;</span><span class="token property">height</span><span class="token punctuation">:</span> 200px<span class="token punctuation">;</span></span><span class="token punctuation">"</span></span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript">
    <span class="token comment">// 选择元素</span>
    <span class="token keyword">const</span> btn <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"body > button"</span><span class="token punctuation">)</span>
    <span class="token keyword">var</span> txtbox <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".result"</span><span class="token punctuation">)</span>
    <span class="token comment">// 绑定事件</span>
    btn<span class="token punctuation">.</span><span class="token function-variable function">onclick</span><span class="token operator">=</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
        <span class="token comment">// 创建对象</span>
        <span class="token keyword">const</span> xhr <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">XMLHttpRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">// 初始化对象http不可以省略</span>
        xhr<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token string">'GET'</span><span class="token punctuation">,</span><span class="token string">"http://127.0.0.1:9000/server"</span><span class="token punctuation">)</span>
        <span class="token comment">// 发送请求</span>
        xhr<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">// 当xhr状态发生改变的时候时间</span>
        <span class="token comment">// readystate表示状态分别是</span>
        <span class="token comment">// 0: 没有初始化,1: open结束, 2: send结束, 3: 收到部分结果, 4: 收到所有结构</span>
        xhr<span class="token punctuation">.</span><span class="token function-variable function">onreadystatechange</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
            <span class="token keyword">if</span><span class="token punctuation">(</span>xhr<span class="token punctuation">.</span>readyState<span class="token operator">===</span><span class="token number">4</span> <span class="token operator">&amp;&amp;</span> xhr<span class="token punctuation">.</span>status <span class="token operator">>=</span> <span class="token number">200</span> <span class="token operator">&amp;&amp;</span> xhr<span class="token punctuation">.</span>status <span class="token operator">&lt;</span> <span class="token number">300</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
                <span class="token comment">// 打印测试内容</span>
                console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>xhr<span class="token punctuation">.</span>status<span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token comment">// 状态码</span>
                console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>xhr<span class="token punctuation">.</span>statusText<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">// 状态字符</span>
                console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>xhr<span class="token punctuation">.</span><span class="token function">getAllResponseHeaders</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token comment">// 响应头 </span>
                console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>xhr<span class="token punctuation">.</span>response<span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token comment">// 响应体</span>
                <span class="token comment">// 修改元素</span>
                txtbox<span class="token punctuation">.</span>innerHTML<span class="token operator">=</span>xhr<span class="token punctuation">.</span>response
            <span class="token punctuation">&#125;</span>
        <span class="token punctuation">&#125;</span>
    <span class="token punctuation">&#125;</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span> </code></pre></li>
<li>总结<br />
我们使用Ajax实际上就是使用了一系列JS的API,包括四个步骤
<ul>
<li><code>const xhr = new XMLHttpRequest();</code>创建一个Ajax请求</li>
<li><code>xhr.open('GET',"http://127.0.0.1:9000/server")</code>初始化一个Ajax对象</li>
<li><code>xhr.send();</code>发送这个对象</li>
<li><code>xhr.onreadystatechange</code>绑定对象变化进行操作</li>
</ul>
我们有几个变量表示对象状态
<ul>
<li><code>xhr.readystate</code>: 0: 没有初始化,1: open结束, 2: send结束,
3: 收到部分结果, 4: 收到所有结构</li>
<li><code>xhr.status</code>: 响应状态码</li>
<li><code>xhr.statusText</code>: 响应状态字符</li>
<li><code>xhr.getAllResponseHeaders</code>: 响应头</li>
<li><code>xhr.response</code>: 响应体</li>
</ul></li>
</ul>
<p><strong>POST部分</strong></p>
<ul>
<li>服务端设置 <pre class="language-js" data-language="js"><code class="language-js">app<span class="token punctuation">.</span><span class="token function">post</span><span class="token punctuation">(</span><span class="token string">"/"</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span>res</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
  res<span class="token punctuation">.</span><span class="token function">setHeader</span><span class="token punctuation">(</span><span class="token string">'Access-Control-Allow-Origin'</span><span class="token punctuation">,</span><span class="token string">'*'</span><span class="token punctuation">)</span>
  res<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token string">"OK"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre> 服务端只是把get修改为了post</li>
<li>HTML设置<br />
事件监听函数内部修改 <pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">const</span> xhr <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">XMLHttpRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
xhr<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token string">'POST'</span><span class="token punctuation">,</span> <span class="token string">"http://127.0.0.1:9000"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 我们在这里配置我们需要发送的信息</span>
xhr<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token string">'user=Liu&amp;passwd=hey'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
xhr<span class="token punctuation">.</span><span class="token function-variable function">onreadystatechange</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span><span class="token operator">...</span><span class="token punctuation">&#125;</span></code></pre></li>
</ul>
<p><strong>设置请求头</strong></p>
<ul>
<li>设置预定义的请求头<br />
只需要在请求处进行修改，例如 <pre class="language-js" data-language="js"><code class="language-js">xhr<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token operator">...</span><span class="token punctuation">)</span>
xhr<span class="token punctuation">.</span><span class="token function">setRequestHeader</span><span class="token punctuation">(</span><span class="token string">'Content-Type'</span><span class="token punctuation">,</span> <span class="token string">'application/x-www-form-urlencoded'</span><span class="token punctuation">)</span>
xhr<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token operator">...</span><span class="token punctuation">)</span></code></pre></li>
<li>自定义请求头<br />
在HTML部分 <pre class="language-js" data-language="js"><code class="language-js">xhr<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token operator">...</span><span class="token punctuation">)</span>
xhr<span class="token punctuation">.</span><span class="token function">setRequestHeader</span><span class="token punctuation">(</span><span class="token string">'Content-Type'</span><span class="token punctuation">,</span> <span class="token string">'application/x-www-form-urlencoded'</span><span class="token punctuation">)</span>
xhr<span class="token punctuation">.</span><span class="token function">setRequestHeader</span><span class="token punctuation">(</span><span class="token string">'defMe'</span><span class="token punctuation">,</span> <span class="token string">'LiuKaieui'</span><span class="token punctuation">)</span>      <span class="token comment">// 举例，参数分别是键值</span>
xhr<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token operator">...</span><span class="token punctuation">)</span></code></pre>
此时，出于浏览器安全设置，我们无法发送包，并报错数据头，我们需要修改服务端
<pre class="language-js" data-language="js"><code class="language-js">app<span class="token punctuation">.</span><span class="token function">all</span><span class="token punctuation">(</span><span class="token string">"/"</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span>res</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>      <span class="token comment">// 其次，由于浏览器会使用get校验服务器权限，所以必须写Get方法，我们直接写成all</span>
    res<span class="token punctuation">.</span><span class="token function">setHeader</span><span class="token punctuation">(</span><span class="token string">'Access-Control-Allow-Origin'</span><span class="token punctuation">,</span><span class="token string">'*'</span><span class="token punctuation">)</span>
    res<span class="token punctuation">.</span><span class="token function">setHeader</span><span class="token punctuation">(</span><span class="token string">'Access-Control-Allow-Headers'</span><span class="token punctuation">,</span><span class="token string">'*'</span><span class="token punctuation">)</span>   <span class="token comment">// 首先要修改这里，支持所有头</span>
    res<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token string">"OK"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></li>
</ul>
<h3 id="json支持">JSON支持</h3>
<p>我们希望服务端向网页传送一个对象，但是默认是不支持的，很容易想到的方法就是服务端把对象转换为JSON,客户端讲JSON字符串转化为对象，有两种方法实现</p>
<ul>
<li>手动实现<br />
服务端只需要讲对象转换为JSON传出即可 <pre class="language-js" data-language="js"><code class="language-js">app<span class="token punctuation">.</span><span class="token function">all</span><span class="token punctuation">(</span><span class="token string">"/json-server"</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span>res</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
  <span class="token keyword">let</span> tmp <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token string-property property">"name"</span><span class="token operator">:</span> <span class="token string">"Liu"</span><span class="token punctuation">,</span><span class="token string-property property">"Age"</span><span class="token operator">:</span> <span class="token number">12</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
  res<span class="token punctuation">.</span><span class="token function">setHeader</span><span class="token punctuation">(</span><span class="token string">'Access-Control-Allow-Origin'</span><span class="token punctuation">,</span><span class="token string">'*'</span><span class="token punctuation">)</span>
  res<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>tmp<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 实际上不stringfy也可以</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
网页只需要把收到的对讲转化为对象就可以了(事件监听内部)
<pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">const</span> rxh<span class="token operator">=</span><span class="token keyword">new</span> <span class="token class-name">XMLHttpRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
rxh<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"POST"</span><span class="token punctuation">,</span><span class="token string">"http://127.0.0.1:9000/json-server"</span><span class="token punctuation">)</span>
rxh<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
rxh<span class="token punctuation">.</span><span class="token function-variable function">onreadystatechange</span><span class="token operator">=</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span>rxh<span class="token punctuation">.</span>readyState<span class="token operator">===</span><span class="token number">4</span> <span class="token operator">&amp;&amp;</span> rxh<span class="token punctuation">.</span>status <span class="token operator">>=</span><span class="token number">200</span> <span class="token operator">&amp;&amp;</span> rxh<span class="token punctuation">.</span>status <span class="token operator">&lt;</span><span class="token number">300</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
        console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>rxh<span class="token punctuation">.</span>response<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span></code></pre></li>
<li>设置响应头实现<br />
设置响应类型后，我们就不需要手动转换了，浏览器收到JSON字符串后会自动转换，reponse就是一个对象
<pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">const</span> rxh<span class="token operator">=</span><span class="token keyword">new</span> <span class="token class-name">XMLHttpRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
rxh<span class="token punctuation">.</span>responseType<span class="token operator">=</span><span class="token string">'json'</span><span class="token punctuation">;</span>     <span class="token comment">// 设置响应类型，无需设置header</span>
rxh<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"POST"</span><span class="token punctuation">,</span><span class="token string">"http://127.0.0.1:9000/json-server"</span><span class="token punctuation">)</span>
rxh<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
rxh<span class="token punctuation">.</span><span class="token function-variable function">onreadystatechange</span><span class="token operator">=</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span>rxh<span class="token punctuation">.</span>readyState<span class="token operator">===</span><span class="token number">4</span> <span class="token operator">&amp;&amp;</span> rxh<span class="token punctuation">.</span>status <span class="token operator">>=</span><span class="token number">200</span> <span class="token operator">&amp;&amp;</span> rxh<span class="token punctuation">.</span>status <span class="token operator">&lt;</span><span class="token number">300</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
        console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>rxh<span class="token punctuation">.</span>response<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span></code></pre></li>
</ul>
<h3 id="ie缓存问题">IE缓存问题</h3>
<p>IE(10-)会对Ajax的请求结果进行缓存，会导致下次Ajax请求得到缓存的结果，IE根据请求的url/body进行判断是否使用缓存，我们只需要在请求的时候加一个时间戳(<code>"...?t="+Date.now()</code>),很多工具都自动实现了这个功能</p>
<h3 id="请求的取消与重发">请求的取消与重发</h3>
<p><strong>超时自动取消</strong></p>
<p>可以制定获取请求的最长时间，超时后浏览器会<strong>自动</strong>取消请求。方法设置XMLHttpRequest的属性：<code>.timeout</code>:
网络超时时间(ms)，<code>.ontimeout</code>: 超时回调函数函数名,
<code>.onerror</code>: 网络错误回调函数名</p>
<ul>
<li>设置服务器, 我们设置一个2000ms的延迟模拟网络延时 <pre class="language-js" data-language="js"><code class="language-js">app<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">"/"</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span>res</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
  res<span class="token punctuation">.</span><span class="token function">setHeader</span><span class="token punctuation">(</span><span class="token string">'Access-Control-Allow-Origin'</span><span class="token punctuation">,</span><span class="token string">'*'</span><span class="token punctuation">)</span>
  <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>res<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token string">"You Get Response"</span><span class="token punctuation">)</span><span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token number">3000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span></code></pre></li>
<li>设置Ajax函数(事件内部的部分) <pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">var</span> hrx <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">XMLHttpRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token comment">// 设置超时时间，设置为2000ms的时候必然超时，4000应该不超时</span>
  hrx<span class="token punctuation">.</span>timeout<span class="token operator">=</span><span class="token number">4000</span><span class="token punctuation">;</span>
  <span class="token comment">// 超时回调函数</span>
  hrx<span class="token punctuation">.</span><span class="token function-variable function">ontimeout</span><span class="token operator">=</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span><span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">"Network Too Slow"</span><span class="token punctuation">)</span><span class="token punctuation">&#125;</span>
  <span class="token comment">// 网络错误回调函数</span>
  hrx<span class="token punctuation">.</span><span class="token function-variable function">onerror</span><span class="token operator">=</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span><span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">"Network ERROR"</span><span class="token punctuation">)</span><span class="token punctuation">&#125;</span>
  <span class="token comment">// 之后一切正常</span>
  hrx<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"GET"</span><span class="token punctuation">,</span><span class="token string">"http://127.0.0.1:9000"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  hrx<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  hrx<span class="token punctuation">.</span><span class="token function-variable function">onreadystatechange</span><span class="token operator">=</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
      <span class="token keyword">if</span><span class="token punctuation">(</span>hrx<span class="token punctuation">.</span>readyState <span class="token operator">===</span> <span class="token number">4</span> <span class="token operator">&amp;&amp;</span> hrx<span class="token punctuation">.</span>status <span class="token operator">>=</span> <span class="token number">200</span> <span class="token operator">&amp;&amp;</span> hrx<span class="token punctuation">.</span>status <span class="token operator">&lt;</span> <span class="token number">300</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
          txtBox<span class="token punctuation">.</span>innerHTML<span class="token operator">=</span>hrx<span class="token punctuation">.</span>response
      <span class="token punctuation">&#125;</span>
  <span class="token punctuation">&#125;</span></code></pre></li>
</ul>
<p><strong>手动取消请求</strong></p>
<pre class="language-js" data-language="js"><code class="language-js">hrx<span class="token punctuation">.</span><span class="token function">abord</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>就可以直接取消</p>
<p><strong>Ajax 重新发送请求</strong></p>
<p>我们应该设置用户连点的时候取消上一次的请求以减小服务器压力，只要设置一个flag标记是否正在发送即可</p>
<h2 id="jquery的ajax">jQuery的Ajax</h2>
<ul>
<li>jQuery有三个函数实现Ajax请求，分别是<code>$.get()</code>,<code>$.post()</code>,<code>$.ajax()</code></li>
<li><code>$.get()</code>与<code>$.post()</code>类似，调用方法是
<pre class="language-js" data-language="js"><code class="language-js">$<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>
  url链接<span class="token punctuation">,</span>
  <span class="token punctuation">&#123;</span>要发送的对象<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
  <span class="token punctuation">(</span><span class="token parameter">d</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>收到对象的回调函数<span class="token punctuation">,</span> d是获取的内容<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
  <span class="token string">"JSON"</span><span class="token operator">/</span><span class="token string">"xml"</span><span class="token operator">/</span><span class="token string">"html"</span><span class="token operator">/</span><span class="token string">"text"</span><span class="token operator">/</span><span class="token string">"script"</span><span class="token operator">/</span><span class="token string">"json"</span><span class="token operator">/</span><span class="token string">"jsonp"</span> <span class="token comment">//收到数据的类型，例如这里如果写了"JSON",那么服务器发送JSON字符串，这边收到后会自动转换为对象</span>
<span class="token punctuation">)</span></code></pre></li>
<li><code>$.ajax()</code>是一个通用的方法 <pre class="language-js" data-language="js"><code class="language-js">$<span class="token punctuation">.</span><span class="token function">ajax</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span>                                <span class="token comment">// 所有的参数一起是一个对象</span>
    <span class="token literal-property property">url</span><span class="token operator">:</span><span class="token string">"http://127.0.0.1:9000"</span><span class="token punctuation">,</span>        <span class="token comment">// 请求链接</span>
    <span class="token literal-property property">data</span><span class="token operator">:</span><span class="token punctuation">&#123;</span><span class="token string-property property">"a"</span><span class="token operator">:</span><span class="token number">100</span><span class="token punctuation">,</span><span class="token string-property property">"b"</span><span class="token operator">:</span><span class="token number">200</span><span class="token punctuation">&#125;</span><span class="token punctuation">,</span>             <span class="token comment">// 传输数据对象</span>
    <span class="token literal-property property">type</span><span class="token operator">:</span><span class="token string">"GET"</span><span class="token punctuation">,</span>                         <span class="token comment">// 传输方式</span>
    <span class="token literal-property property">dataType</span><span class="token operator">:</span><span class="token string">"JSON"</span><span class="token punctuation">,</span>                    <span class="token comment">// 数据类型</span>
    <span class="token function-variable function">success</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">d</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>d<span class="token punctuation">)</span><span class="token punctuation">&#125;</span><span class="token punctuation">,</span>     <span class="token comment">// 成功回调函数</span>
    <span class="token function-variable function">error</span><span class="token operator">:</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"ERR"</span><span class="token punctuation">)</span><span class="token punctuation">&#125;</span><span class="token punctuation">,</span>     <span class="token comment">// 失败回调函数</span>
    <span class="token literal-property property">timeout</span><span class="token operator">:</span><span class="token number">2000</span><span class="token punctuation">,</span>                       <span class="token comment">// 超时时间</span>
    <span class="token literal-property property">headers</span><span class="token operator">:</span><span class="token punctuation">&#123;</span>                           <span class="token comment">// 请求头 可以是标准的，也可以是自定义的</span>
        <span class="token constant">A</span><span class="token operator">:</span><span class="token number">100</span>                           <span class="token comment">// 如果是自定义的要在服务端进行设置，见`使用原生...>设置请求头>自定义请求头`</span>
    <span class="token punctuation">&#125;</span>   
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span></code></pre>
参数还有很多，详见<a
target="_blank" rel="noopener" href="https://www.w3school.com.cn/jquery/ajax_ajax.asp">文档</a></li>
</ul>
<p>get/post使用简单，ajax功能多，按情况使用即可</p>
<h2 id="使用axios发送ajax简易">使用Axios发送Ajax[简易]</h2>
<p>是一个热门的AJAX请求库,支持promise,
支持NodeJS,支持取消请求,支持拦截器,简易的使用方式是</p>
<pre class="language-js" data-language="js"><code class="language-js">axios<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">"http://127.0.0.1:9000"</span><span class="token punctuation">,</span><span class="token punctuation">&#123;</span>   <span class="token comment">// 请求地址是一个单独的参数</span>
    <span class="token literal-property property">params</span><span class="token operator">:</span><span class="token punctuation">&#123;</span>                          <span class="token comment">// 请求的参数，也就是.com?A=1&amp;b=2那部分，使用Axios你可以不用拼串</span>
        <span class="token literal-property property">id</span><span class="token operator">:</span><span class="token number">100</span><span class="token punctuation">,</span>
        <span class="token literal-property property">un</span><span class="token operator">:</span><span class="token number">7</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
    <span class="token literal-property property">headers</span><span class="token operator">:</span><span class="token punctuation">&#123;</span>                         <span class="token comment">// 自定义请求头</span>
        <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token number">123</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>获取请求结果是要使用Promise直接then(),
Axios进行post的时候还可以使用params进行链接定制，但是参数列表有所不同<code>axios.post(url,&#123;data对象&#125;,&#123;参数对象&#125;)</code></p>
<p>也可以使用axios函数直接发送 <pre class="language-js" data-language="js"><code class="language-js"><span class="token comment">// 发送 POST 请求</span>
<span class="token function">axios</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span>
  <span class="token literal-property property">method</span><span class="token operator">:</span> <span class="token string">'post'</span><span class="token punctuation">,</span>
  <span class="token literal-property property">url</span><span class="token operator">:</span> <span class="token string">'/user/12345'</span><span class="token punctuation">,</span>
  <span class="token literal-property property">data</span><span class="token operator">:</span> <span class="token punctuation">&#123;</span>
    <span class="token literal-property property">firstName</span><span class="token operator">:</span> <span class="token string">'Fred'</span><span class="token punctuation">,</span>
    <span class="token literal-property property">lastName</span><span class="token operator">:</span> <span class="token string">'Flintstone'</span>
  <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre> 详见<a
target="_blank" rel="noopener" href="http://www.axios-js.com/zh-cn/docs/">官方文档</a></p>
<h2 id="使用fetch发送请求">使用fetch发送请求</h2>
<p>fetch是一个window的对象，可以发送Ajax请求，返回一个Promise对象，fetch是前端发展的一种新技术产物。可以简单的理解为是XMLHttpRequest的参数简化版</p>
<p>Fetch API 提供了一个
JavaScript接口，用于访问和操纵HTTP管道的部分，例如请求和响应。它还提供了一个全局
fetch()方法，该方法提供了一种简单，合理的方式来跨网络异步获取资源。这种功能以前是使用
XMLHttpRequest实现的。Fetch提供了一个更好的替代方法，可以很容易地被其他技术使用，例如
Service
Workers。Fetch还提供了单个逻辑位置来定义其他HTTP相关概念，例如CORS和HTTP的扩展。fetch代表着更先进的技术方向，但是目前兼容性不是很好，在项目中使用的时候得慎重。</p>
<p>格式是<code>fetch(input[, init]);</code></p>
<ul>
<li>input写url/requert对象</li>
<li>init写配置对象，有(详见<a
target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/fetch">文档</a>)
<ul>
<li>method: 请求使用的方法，如 GET、POST。</li>
<li>headers: 请求的头信息，形式为 Headers 的对象或包含 ByteString
值的对象字面量。</li>
<li>body: 请求的 body 信息：可能是一个 Blob、BufferSource
(en-US)、FormData、URLSearchParams 或者 USVString 对象。注意 GET 或 HEAD
方法的请求不能包含 body 信息。</li>
<li>mode: 请求的模式，如 cors、 no-cors 或者 same-origin。</li>
</ul></li>
</ul>
<pre class="language-js" data-language="js"><code class="language-js"><span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">'http://example.com/movies.json'</span><span class="token punctuation">)</span>
  <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    <span class="token keyword">return</span> response<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">)</span></code></pre>
<p>在使用fetch的时候需要注意：</p>
<ul>
<li>当接收到一个代表错误的 HTTP 状态码时，从 fetch()返回的 Promise
不会被标记为 reject， 即使该 HTTP 响应的状态码是 404 或
500。相反，它会将 Promise 状态标记为 resolve （但是会将 resolve
的返回值的 ok 属性设置为 false
），仅当网络故障时或请求被阻止时，才会标记为 reject。</li>
<li>默认情况下，fetch 不会从服务端发送或接收任何 cookies,
如果站点依赖于用户 session，则会导致未经认证的请求（要发送
cookies，必须设置 credentials 选项）。</li>
</ul>
<h2 id="ajax跨域">Ajax跨域</h2>
<p>同源策略是网景提出的浏览器安全策略，他要求Ajax请求的网页与目标服务器url,端口,协议是一致的，Ajax默认遵守这个策略，违背同源就是跨域</p>
<h3 id="jsonp解决跨域问题">JSONP解决跨域问题</h3>
<p>JSONP是一个非官方的跨域解决方案，只支持GET请求，利用了<code>&lt;script&gt;</code>标签的特性实现跨域，HTML的很多标签本身就是支持跨域的，例如<code>&lt;img&gt;</code>，<code>&lt;script&gt;</code>会引用外部的文件</p>
<p>首先要在浏览器中定义一个函数用于更新内容，例如我想在跨域请求后将结果更新到<code>#box</code>上
<pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">process_JSONP</span><span class="token punctuation">(</span><span class="token parameter">t</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
  <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#box"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">text</span><span class="token punctuation">(</span>t<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre> 跨域被请求端设置(请求端为127.0.0.1) <pre class="language-js" data-language="js"><code class="language-js">app<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">"/jsonp-server"</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span>res</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
  str <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringfy</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span><span class="token string-property property">"name"</span><span class="token operator">:</span><span class="token string">"我是一个被请求的对象"</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
  res<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">process_JSONP(</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>str<span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token string">)</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token comment">// JS拼串</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span></code></pre>
请求端在process_JSONP定义后引用JS <pre class="language-html" data-language="html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://127.0.0.1/jsonp-server<span class="token punctuation">"</span></span><span class="token punctuation">></span></span></code></pre>
这样，服务端返回字符串被当作了js,执行了<code>process_JSONP()</code>命令,对网页进行了更新</p>
<p><strong>原生JSONP实例</strong></p>
<p>我们想要实现的功能是，点击<code>#A</code>，浏览器发送跨域请求，服务器发送结果，收到结果后，如果是true,更新.stat背景色为绿色，否则为红色</p>
<p>前端JS设置 <pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">process_jsonp</span><span class="token punctuation">(</span><span class="token parameter">stat</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>     <span class="token comment">// 获取后的处理函数</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span>stat<span class="token punctuation">)</span>document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".stat"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>style <span class="token operator">=</span> <span class="token string">"background-color:#bfa;"</span>
    <span class="token keyword">else</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".stat"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>style <span class="token operator">=</span> <span class="token string">"background-color:#f11;"</span>
<span class="token punctuation">&#125;</span>
btnA <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"#A"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
btnA<span class="token punctuation">.</span><span class="token function-variable function">onclick</span><span class="token operator">=</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    <span class="token keyword">const</span> jsLab <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">"script"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>     <span class="token comment">// 创建一个script标签</span>
    jsLab<span class="token punctuation">.</span>src <span class="token operator">=</span> <span class="token string">"http://127.0.0.1:9000/jsonp"</span><span class="token punctuation">;</span>          <span class="token comment">// 设置一个script标签的src</span>
    document<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>jsLab<span class="token punctuation">)</span>                    <span class="token comment">// 将script标签添加到网页</span>
<span class="token punctuation">&#125;</span></code></pre></p>
<p>后端只返回<code>true</code></p>
<p>因为我们只能写url,不能指定请求头，请求体，我们只能实现get请求</p>
<p><strong>jQuery实现JSONP实例</strong></p>
<p>jQuery的get/post函数默认当然是不支持跨域的，但是jQuery还有一个getJSON函数，这个函数本来是用来请求JSON，但是这个函数在jQuery底层实现的时候是先对参数的url进行解析，然后使用了上面这种script标签的方法获取JSON对象，所以这个方法是支持跨域的，我们可以利用这个特性。</p>
<p>首先了解函数功能，参数列表是<code>getJSON(url,callbackFunction)</code>，当函数发现url字符串有<code>callback=?</code>，他会自动替换成<code>callback=一个字符串</code>，之后jQuery会注册一个名字叫这个字符串的方法，这个方法内容就是第二个参数于是我们利用这个特性实现JSONP</p>
<p>我们的目标是：
前端点击<code>#A</code>，后端发回消息，前端将<code>.stat</code>的内容替换为响应结果</p>
<p>前端代码 <pre class="language-js" data-language="js"><code class="language-js"><span class="token function">$</span><span class="token punctuation">(</span><span class="token string">"#A"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">click</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
  $<span class="token punctuation">.</span><span class="token function">getJSON</span><span class="token punctuation">(</span><span class="token string">"http://127.0.0.1:9000/jsonp?callback=?"</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token parameter">d</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>     <span class="token comment">// 这里callback=?会在请求的时候被替换</span>
    <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">".stat"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">text</span><span class="token punctuation">(</span>d<span class="token punctuation">)</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span></code></pre></p>
<p>后端代码 <pre class="language-js" data-language="js"><code class="language-js">app<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">"/jsonp"</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span>res</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
  <span class="token keyword">let</span> cb <span class="token operator">=</span> req<span class="token punctuation">.</span>query<span class="token punctuation">.</span>callback<span class="token punctuation">;</span>          <span class="token comment">// 获取请求中的随机子复查u年</span>
  res<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>cb<span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token string">("Wow You Get!")</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">// 调用函数</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span></code></pre></p>
<p>当然这个方法是不适合大量数据请求的</p>
<h3 id="cors解决跨域问题">CORS解决跨域问题</h3>
<p>CORS(Cross-Origin Resource
Sharing,跨域资源共享)是一种官方的跨域解决方案，不需要在客户端进行任何操作，在服务端进行修改就可以直接支持<strong>get</strong>/<strong>post</strong></p>
<p>只需要在服务器上加上响应头<code>Access-Control-Allow-Origin: *</code>即可，如果想要设置允许特定的跨域请求，例如只允许127.0.0.1:5050的，那么只需要修改为<code>Access-Control-Allow-Origin: 127.0.0.1:5050</code></p>
<p><strong>实例</strong></p>
<p><code>#btnB</code>点击console显示获取的跨域结果</p>
<p>前端JS <pre class="language-js" data-language="js"><code class="language-js">btnB<span class="token punctuation">.</span><span class="token function-variable function">onclick</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
  <span class="token keyword">const</span> xhr <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">XMLHttpRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  xhr<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token string">"GET"</span><span class="token punctuation">,</span><span class="token string">"http://127.0.0.1:9000/jsonp"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  xhr<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  xhr<span class="token punctuation">.</span><span class="token function-variable function">onreadystatechange</span><span class="token operator">=</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span>xhr<span class="token punctuation">.</span>readyState <span class="token operator">===</span> <span class="token number">4</span> <span class="token operator">&amp;&amp;</span> xhr<span class="token punctuation">.</span>status <span class="token operator">>=</span><span class="token number">200</span> <span class="token operator">&amp;&amp;</span> xhr<span class="token punctuation">.</span>status<span class="token operator">&lt;</span><span class="token number">300</span><span class="token punctuation">)</span>
      console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>xhr<span class="token punctuation">.</span>response<span class="token punctuation">)</span>
  <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span></code></pre> 后端JS <pre class="language-js" data-language="js"><code class="language-js">app<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">"/jsonp"</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token parameter">req<span class="token punctuation">,</span>res</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
  res<span class="token punctuation">.</span><span class="token function">setHeader</span><span class="token punctuation">(</span><span class="token string">'Access-Control-Allow-Origin'</span><span class="token punctuation">,</span><span class="token string">'*'</span><span class="token punctuation">)</span>
  res<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Wow You Get!</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span></code></pre>
CORS不止定义了这一个响应头，还有</p>
<ul>
<li><code>Access-Control-Allow-Origin</code>:
指示请求的资源能共享给哪些域。</li>
<li><code>Access-Control-Allow-Credentials</code>:
指示当请求的凭证标记为 true 时，是否响应该请求。</li>
<li><code>Access-Control-Allow-Headers</code>:
用在对预请求的响应中，指示实际的请求中可以使用哪些 HTTP 头。</li>
<li><code>Access-Control-Allow-Methods</code>:
指定对预请求的响应中，哪些 HTTP 方法允许访问请求的资源。</li>
<li><code>Access-Control-Expose-Headers</code>: 指示哪些 HTTP
头的名称能在响应中列出。</li>
<li><code>Access-Control-Max-Age</code>:
指示预请求的结果能被缓存多久。</li>
<li><code>Access-Control-Request-Headers</code>:
用于发起一个预请求，告知服务器正式请求会使用那些 HTTP 头。</li>
<li><code>Access-Control-Request-Method</code>:
用于发起一个预请求，告知服务器正式请求会使用哪一种 HTTP 请求方法。</li>
<li><code>Origin</code>: 指示获取资源的请求是从什么域发起的。</li>
</ul>
<p>详见<a
target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Glossary/CORS">MDN文档</a></p>
<h2 id="axios的理解与使用">Axios的理解与使用</h2>
<p>前置内容: Promise &amp; AJAX</p>
<h3 id="json-server的使用">JSON Server的使用</h3>
<p><a target="_blank" rel="noopener" href="https://github.com/typicode/json-server">JSON
Server</a>是一个利用<a
target="_blank" rel="noopener" href="https://www.runoob.com/w3cnote/restful-architecture.html">RESTful
API</a>快速搭建的http服务框架,
可以无代码创建一个http服务，这个服务可以在请求的时候返回指定的JSON对象</p>
<ul>
<li><strong>安装:</strong> <pre class="language-js" data-language="js"><code class="language-js">sudo npm install <span class="token operator">-</span>g json<span class="token operator">-</span>server</code></pre></li>
<li><strong>创建文件</strong>:
<code>./db.json</code>,随便写入一个对象，例如 <pre class="language-json" data-language="json"><code class="language-json"><span class="token punctuation">&#123;</span>
  <span class="token property">"posts"</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">&#123;</span>
    <span class="token property">"id"</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
    <span class="token property">"title"</span><span class="token operator">:</span> <span class="token string">"json-server"</span><span class="token punctuation">,</span>
    <span class="token property">"author"</span><span class="token operator">:</span> <span class="token string">"typicode"</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
  <span class="token property">"comments"</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">&#123;</span>
    <span class="token property">"id"</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
    <span class="token property">"body"</span><span class="token operator">:</span> <span class="token string">"some comment"</span><span class="token punctuation">,</span>
    <span class="token property">"postId"</span><span class="token operator">:</span> <span class="token number">1</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">]</span><span class="token punctuation">,</span>j s o n</code></pre>
上面这个对象的意思是，当访问localhost:3000/posts的时候返回对应数组对象，当访问http://localhost:3000/posts?id=1的时候返回一个数组，数组中包含id=1的对象，其余以此类推</li>
<li><strong>启动服务</strong>: 同路径下执行 <pre class="language-js" data-language="js"><code class="language-js">json<span class="token operator">-</span>server <span class="token operator">--</span>watch db<span class="token punctuation">.</span>json</code></pre></li>
</ul>
<h3 id="axios基本使用">Axios基本使用</h3>
<p>Axios是一个基于Promise的http客户端，运行在浏览器/NodeJS上，向远程发送Ajax/http请求,
支持请求响应拦截器，支持请求响应的数据解析，支持取消请求，支持JSON处理，支持扩展攻击的防护</p>
<ul>
<li>可以使用npm安装在Node上(或在项目打包的时候)</li>
<li>可以使用script标签引入</li>
</ul>
<p>Axios被引入后与jQuery类似，只有一个axios函数</p>
<p><strong>尝试实现Get/Post/Put/Delete请求</strong></p>
<p>实现点击不同请求方式的按钮，发送不同请求到JSON-Server</p>
<p>前端JS <pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> btn_get <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelectorAll</span><span class="token punctuation">(</span><span class="token string">"button"</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> btn_post <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelectorAll</span><span class="token punctuation">(</span><span class="token string">"button"</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> btn_delete <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelectorAll</span><span class="token punctuation">(</span><span class="token string">"button"</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> btn_put <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelectorAll</span><span class="token punctuation">(</span><span class="token string">"button"</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> box_txt <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">".stat"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

btn_get<span class="token punctuation">.</span><span class="token function-variable function">onclick</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>j s o n
    <span class="token function">axios</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span>
        <span class="token literal-property property">method</span>  <span class="token operator">:</span> <span class="token string">'GET'</span><span class="token punctuation">,</span>
        <span class="token literal-property property">url</span>     <span class="token operator">:</span> <span class="token string">'http://127.0.0.1:3000/posts'</span><span class="token punctuation">,</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">d</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
        box_txt<span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>d<span class="token punctuation">.</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span> 

<span class="token comment">// JSON-Server文档写到，post可以实现添加对象，直接使用post就可以将请求体添加到对象</span>
btn_post<span class="token punctuation">.</span><span class="token function-variable function">onclick</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    <span class="token function">axios</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span>
        <span class="token literal-property property">method</span>  <span class="token operator">:</span> <span class="token string">'POST'</span><span class="token punctuation">,</span>
        <span class="token literal-property property">url</span>     <span class="token operator">:</span> <span class="token string">'http://127.0.0.1:3000/posts'</span><span class="token punctuation">,</span>
        <span class="token comment">// 请求体</span>
        <span class="token literal-property property">data</span>    <span class="token operator">:</span> <span class="token punctuation">&#123;</span>
            <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"Test1"</span><span class="token punctuation">,</span>
            <span class="token literal-property property">author</span><span class="token operator">:</span><span class="token string">"Test1"</span>
        <span class="token punctuation">&#125;</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">d</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>j s o n
        box_txt<span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>d<span class="token punctuation">.</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span> 

<span class="token comment">// JSON-Server文档表示，put可以实现修改对象，使用put, 在链接上指定ID, 将修改成的内容作为data传参即可</span>
btn_put<span class="token punctuation">.</span><span class="token function-variable function">onclick</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>j s o n
        <span class="token literal-property property">method</span>  <span class="token operator">:</span> <span class="token string">'PUT'</span><span class="token punctuation">,</span>
        <span class="token literal-property property">url</span>     <span class="token operator">:</span> <span class="token string">'http://127.0.0.1:3000/posts/2'</span><span class="token punctuation">,</span>
        <span class="token comment">// 请求体</span>
        <span class="token literal-property property">data</span>    <span class="token operator">:</span> <span class="token punctuation">&#123;</span>
            <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"Test1ANN"</span><span class="token punctuation">,</span>
            <span class="token literal-property property">author</span><span class="token operator">:</span><span class="token string">"Test1BNN"</span>
        <span class="token punctuation">&#125;</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">d</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>j s o <span class="token function">ntringify</span><span class="token punctuation">(</span>d<span class="token punctuation">.</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>j s o n
<span class="token comment">// JSON-Server文档表示，delete可以实现修改对象，使用delete, 在链接上指定ID即可</span>
btn_delete<span class="token punctuation">.</span><span class="token function-variable function">onclick</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    <span class="token function">axios</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span>
        <span class="token literal-property property">method</span>  <span class="token operator">:</span> <span class="token string">'DELETE'</span><span class="token punctuation">,</span>
        <span class="token literal-property property">url</span>     <span class="token operator">:</span> <span class="token string">'http://127.0.0.1:3000/posts/2'</span><span class="token punctuation">,</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">d</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
        box_txt<span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>d<span class="token punctuation">.</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span></code></pre></p>
<p>后端使用数据 <pre class="language-json" data-language="json"><code class="language-json"><span class="token punctuation">&#123;</span>
  <span class="token property">"posts"</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">&#123;</span>
    <span class="token property">"id"</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
    <span class="token property">"title"</span><span class="token operator">:</span> <span class="token string">"json-server"</span><span class="token punctuation">,</span>
    <span class="token property">"author"</span><span class="token operator">:</span> <span class="token string">"typicode"</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">&#125;</span></code></pre>
发送get请求的时候会返回对象，post会增加对象，put会修改对象，delete会删除对象，这是json-server定义的行为方式</p>
<p>除了Axios对象之外，我们还可以使用Axios的方法实现请求的发送，有两种，一个是<code>Axios.request(参数与Axios一样)</code>,还有一种是以请求方法命名的例如<code>Axios.post(url,&#123;post_body&#125;,&#123;configure&#125;)</code>，详见<a
target="_blank" rel="noopener" href="https://github.com/axios/axios#request-method-aliases">文档</a></p>
<p><strong>Axios响应数据结构</strong> <pre class="language-js" data-language="js"><code class="language-js"><span class="token punctuation">&#123;</span>
    <span class="token string-property property">"data"</span><span class="token operator">:</span> <span class="token punctuation">&#123;</span><span class="token operator">...</span><span class="token punctuation">&#125;</span><span class="token punctuation">,</span>                    <span class="token comment">// 响应体对象</span>
    <span class="token string-property property">"status"</span><span class="token operator">:</span> <span class="token number">201</span><span class="token punctuation">,</span>                    <span class="token comment">// 响应状态码</span>
    <span class="token string-property property">"statusText"</span><span class="token operator">:</span> <span class="token string">"Created"</span><span class="token punctuation">,</span>          <span class="token comment">// 响应内容</span>
    <span class="token string-property property">"headers"</span><span class="token operator">:</span> <span class="token punctuation">&#123;</span>                      <span class="token comment">// 响应头</span>
        <span class="token string-property property">"cache-control"</span><span class="token operator">:</span> <span class="token string">"no-cache"</span><span class="token punctuation">,</span>
        <span class="token string-property property">"content-length"</span><span class="token operator">:</span> <span class="token string">"48"</span><span class="token punctuation">,</span>
        <span class="token string-property property">"content-type"</span><span class="token operator">:</span> <span class="token string">"application/json; charset=utf-8"</span><span class="token punctuation">,</span>
        <span class="token string-property property">"expires"</span><span class="token operator">:</span> <span class="token string">"-1"</span><span class="token punctuation">,</span>
        <span class="token string-property property">"location"</span><span class="token operator">:</span> <span class="token string">"http://127.0.0.1:3000/posts/9"</span><span class="token punctuation">,</span>
        <span class="token string-property property">"pragma"</span><span class="token operator">:</span> <span class="token string">"no-cache"</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
    <span class="token string-property property">"config"</span><span class="token operator">:</span> <span class="token punctuation">&#123;</span>                       <span class="token comment">// 请求配置</span>
        <span class="token string-property property">"url"</span><span class="token operator">:</span> <span class="token string">"http://127.0.0.1:3000/posts"</span><span class="token punctuation">,</span>
        <span class="token string-property property">"method"</span><span class="token operator">:</span> <span class="token string">"post"</span>
        <span class="token comment">// ...</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
    <span class="token string-property property">"request"</span><span class="token operator">:</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span>                     <span class="token comment">// 原生的Ajax对象</span>
<span class="token punctuation">&#125;</span></code></pre></p>
<p><strong>Axios请求对象数据结构</strong></p>
<p>这里的请求对象指的是<code>Axios(config)</code>,<code>Axios.request(config)</code>,<code>Axios.post(url,&#123;post_body&#125;,config)</code>...中的config对象，参数有</p>
<p>翻译自文档，英语好可以不看 <pre class="language-json" data-language="json"><code class="language-json"><span class="token punctuation">&#123;</span>
  <span class="token comment">// 访问的URL,如果设置了baseurl(后面会有)，可以直接写后半部分</span>
  url<span class="token operator">:</span> 'http<span class="token operator">:</span><span class="token comment">//127.0.0.1:3000/posts',</span>
  <span class="token comment">// url: '/posts',</span>

  <span class="token comment">// 请求方式</span>
  method<span class="token operator">:</span> 'get'<span class="token punctuation">,</span> <span class="token comment">// default</span>

  <span class="token comment">// baseurl是url最基础的部分，如果这里有填数据，那么请求的时候会把url替换成baseurl+url 除非url被写为绝对路径</span>
  baseURL<span class="token operator">:</span> 'https<span class="token operator">:</span><span class="token comment">//127.0.0.1:3000',</span>

  <span class="token comment">// 在发送请求之前对数据进行处理的函数</span>
  <span class="token comment">// 仅支持 'PUT', 'POST', 'PATCH' and 'DELETE'</span>
  <span class="token comment">// 这是一个函数列表，最后一个函数必须返回字符串/JS的Buffer/JS的Buffer数组</span>
  transformRequest<span class="token operator">:</span> <span class="token punctuation">[</span>function (data<span class="token punctuation">,</span> headers) <span class="token punctuation">&#123;</span>
    <span class="token comment">// ...</span>
    return data;
  <span class="token punctuation">&#125;</span><span class="token punctuation">]</span><span class="token punctuation">,</span>

  <span class="token comment">// 对响应结果进行处理</span>
  transformResponse<span class="token operator">:</span> <span class="token punctuation">[</span>function (data) <span class="token punctuation">&#123;</span>
    <span class="token comment">// ...</span>
    return data;
  <span class="token punctuation">&#125;</span><span class="token punctuation">]</span><span class="token punctuation">,</span>

  <span class="token comment">// 配置请求头信息</span>
  headers<span class="token operator">:</span> <span class="token punctuation">&#123;</span>'X-Requested-With'<span class="token operator">:</span> 'XMLHttpRequest'<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>

  <span class="token comment">// 设置url参数，例如Get的时候向下面这么写，就转化为?ID=12345</span>
  params<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
    ID<span class="token operator">:</span> <span class="token number">12345</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>

  <span class="token comment">// 参数序列化(格式化)函数</span>
  paramsSerializer<span class="token operator">:</span> function (params) <span class="token punctuation">&#123;</span>
    return Qs.stringify(params<span class="token punctuation">,</span> <span class="token punctuation">&#123;</span>arrayFormat<span class="token operator">:</span> 'brackets'<span class="token punctuation">&#125;</span>)
  <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>

  <span class="token comment">// 请求体设置: 支持对象或者字符串，Axios最后都会转换成字符串，仅支持 'PUT', 'POST', 'DELETE , and 'PATCH'</span>
  data<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
    firstName<span class="token operator">:</span> 'Fred'
  <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>  
  <span class="token comment">// data: 'Country=Brasil&amp;City=Belo Horizonte',</span>

  <span class="token comment">// 设置超时时间, 超时后自动取消, 单位ms</span>
  timeout<span class="token operator">:</span> <span class="token number">1000</span><span class="token punctuation">,</span>

  <span class="token comment">// 跨域请求时候设置是否携带cookie</span>
  withCredentials<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token comment">// default</span>

  <span class="token comment">// 设置请求适配器</span>
  adapter<span class="token operator">:</span> function (config) <span class="token punctuation">&#123;</span>
    <span class="token comment">/* ... */</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>

  <span class="token comment">// http的基础认证(有的页面要输入访问的用户名密码)</span>
  auth<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
    username<span class="token operator">:</span> 'janedoe'<span class="token punctuation">,</span>
    password<span class="token operator">:</span> 's00pers3cret'
  <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>

  <span class="token comment">// 设置响应体格式</span>
  responseType<span class="token operator">:</span> 'json'<span class="token punctuation">,</span> <span class="token comment">// default</span>

  <span class="token comment">// 字符集设置</span>
  responseEncoding<span class="token operator">:</span> 'utf8'<span class="token punctuation">,</span> <span class="token comment">// default</span>

  <span class="token comment">// 跨域请求时cookie名设置 防止跨站攻击</span>
  xsrfCookieName<span class="token operator">:</span> 'XSRF-TOKEN'<span class="token punctuation">,</span> <span class="token comment">// default</span>

  <span class="token comment">// 跨域请求头设置</span>
  xsrfHeaderName<span class="token operator">:</span> 'X-XSRF-TOKEN'<span class="token punctuation">,</span> <span class="token comment">// default</span>

  <span class="token comment">// 上传时回调函数</span>
  onUploadProgress<span class="token operator">:</span> function (progressEvent) <span class="token punctuation">&#123;</span>
    <span class="token comment">// ...</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>

  <span class="token comment">// 下载时回调函数</span>
  onDownloadProgress<span class="token operator">:</span> function (progressEvent) <span class="token punctuation">&#123;</span>
    <span class="token comment">// ...</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>

  <span class="token comment">// 响应的最大长度</span>
  maxContentLength<span class="token operator">:</span> <span class="token number">2000</span><span class="token punctuation">,</span>

  <span class="token comment">// 响应体最大长度</span>
  maxBodyLength<span class="token operator">:</span> <span class="token number">2000</span><span class="token punctuation">,</span>

  <span class="token comment">// 如何定义响应成功</span>
  validateStatus<span class="token operator">:</span> function (status) <span class="token punctuation">&#123;</span>
    return status >= <span class="token number">200</span> &amp;&amp; status &lt; <span class="token number">300</span>; <span class="token comment">// default</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
bu kanrects<span class="token operator">:</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token comment">// default</span>

  <span class="token comment">// 设置socket文件位置</span>
  socketPath<span class="token operator">:</span> <span class="token null keyword">null</span><span class="token punctuation">,</span> <span class="token comment">// default</span>

  <span class="token comment">// 请求设置</span>
  httpAgent<span class="token operator">:</span> new http.Agent(<span class="token punctuation">&#123;</span> keepAlive<span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">&#125;</span>)<span class="token punctuation">,</span>
  httpsAgent<span class="token operator">:</span> new https.Agent(<span class="token punctuation">&#123;</span> keepAlive<span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">&#125;</span>)<span class="token punctuation">,</span>

  <span class="token comment">// 代理设置，一般用于Node爬虫</span>
  proxy<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
    protocol<span class="token operator">:</span> 'https'<span class="token punctuation">,</span>
    host<span class="token operator">:</span> '<span class="token number">127.0</span>.<span class="token number">0.1</span>'<span class="token punctuation">,</span>
    port<span class="token operator">:</span> <span class="token number">9000</span><span class="token punctuation">,</span>
    auth<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
      username<span class="token operator">:</span> 'mikeymike'<span class="token punctuation">,</span>
      password<span class="token operator">:</span> 'rapunz3l'
    <span class="token punctuation">&#125;</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>

  <span class="token comment">// 请求取消函数</span>
  cancelToken<span class="token operator">:</span> new CancelToken(function (cancel) <span class="token punctuation">&#123;</span>
  <span class="token punctuation">&#125;</span>)<span class="token punctuation">,</span>bu kan否解压结果(仅用于Node)
  decompress<span class="token operator">:</span> <span class="token boolean">true</span> <span class="token comment">// default</span>

  <span class="token comment">// 可能会在较新版本中删除的向后兼容性过渡选项</span>
  transitional<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
    silentJSONParsing<span class="token operator">:</span> <span class="token boolean">true</span>; <span class="token comment">// default value for the current Axios version</span>
    forcedJSONParsing<span class="token operator">:</span> <span class="token boolean">true</span>;
    clarifyTimeoutError<span class="token operator">:</span> <span class="token boolean">false</span>;
  <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span></code></pre></p>
<p><strong>Axios的默认配置</strong></p>
<p>可以设置config的默认值</p>
<p>直接设置<code>axios.default.config参数 = "XX"</code>，例如<code>axios.default.method = "GET"</code></p>
<p><strong>创建实例对象,发送Axios请求</strong></p>
<p>推荐用于测试请求的API: <a
target="_blank" rel="noopener" href="https://api.apiopen.top/">https://api.apiopen.top/</a></p>
<p>我们可以创建一个叫做duanzi的对象，用于发送请求 <pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">const</span> duanzi <span class="token operator">=</span> axios<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span>
  <span class="token literal-property property">baseURL</span><span class="token operator">:</span><span class="token string">'https://api.apiopen.top/getSingleJoke'</span><span class="token punctuation">,</span>
  <span class="token literal-property property">timeout</span><span class="token operator">:</span><span class="token number">3000</span><span class="token punctuation">,</span>
  <span class="token literal-property property">method</span><span class="token operator">:</span><span class="token string">"get"</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>      

<span class="token function">duanzi</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span>
  <span class="token literal-property property">params</span><span class="token operator">:</span><span class="token punctuation">&#123;</span><span class="token literal-property property">sid</span><span class="token operator">:</span><span class="token number">28654780</span><span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">d</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>d<span class="token punctuation">.</span>data<span class="token punctuation">)</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span></code></pre>
我们使用了axios.creat()函数创建了一个duanzi对象用来获取段子，并且添加了一些参数，这个段子对象是一个函数，这个函数与Axios()的功能是一样的，相当于就是一个设置了默认参数作用域的Axios</p>
<p>我们可以调用函数发送Axios请求，这里参数列表设置sid是测试API文档要求的，我们还可以仿照axios.get()使用duanzi.get()</p>
<h3 id="拦截器">拦截器</h3>
<ul>
<li>拦截器就是一个函数，有两类拦截器，请求拦截器和响应拦截器</li>
<li>拦截器与中间件较为相似，就是在发送请求之前与收到响应之后对config/data进行判断，并抛出resolve/reject</li>
<li>当拦截器抛出结构后，Axios会执行promise链上的对应步骤(继续发送请求还是取消请求等等可以暂时不管)</li>
<li>拦截器与transformRequest/transformResponse有一定的区别，拦截器的返回结果是一个Promise对象，出错可以直接执行Promise链上的对应函数，但是transformRequest/transformResponse是一个函数列表，返回值是发送/收到的数据，前者是用于<strong>判定请求是否合法决定要不要继续运行</strong>的，后者是在<strong>合法基础上对数据进行处理</strong>的，有一定的区别，之后我们将做实验证明他们的关系</li>
</ul>
<p><strong>一个简单使用</strong></p>
<p>先看一个简单的使用如下，不需要理解到底发生了上面 <pre class="language-js" data-language="js"><code class="language-js">axios<span class="token punctuation">.</span>interceptors<span class="token punctuation">.</span>request<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">config</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    <span class="token comment">// 参数就是我们Axios请求中的config,我们可以对他进行判断，修改</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"请求拦截器 成功"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// 这里要返回一个对象用于设置请求</span>
    <span class="token keyword">return</span> config<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"请求拦截器 失败"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// 返回一个Promise的refuse对象</span>
    <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

axios<span class="token punctuation">.</span>interceptors<span class="token punctuation">.</span>response<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    <span class="token comment">// 参数是Axios的默认请求结果</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"响应拦截器 成功"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// 在这里不是必须返回发来的reponse,可以是任意的</span>
    <span class="token keyword">return</span> response<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"响应拦截器 失败"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

axios<span class="token punctuation">.</span><span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span>
    <span class="token literal-property property">method</span>  <span class="token operator">:</span>   <span class="token string">"GET"</span><span class="token punctuation">,</span>
    <span class="token literal-property property">url</span>     <span class="token operator">:</span>   <span class="token string">"http://127.0.0.1:3000/posts"</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">d</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>d<span class="token punctuation">.</span>data<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span></code></pre>
得到的结果是 <pre class="language-none"><code class="language-none">请求拦截器 成功
响应拦截器 成功
&#x2F;&#x2F; 获得的数据</code></pre>
我们大致知道了刚刚运行的顺序是请求拦截器运行，返回config，发收请求，响应拦截器运行，返回结果，打印</p>
<p><strong>拦截器的基本结构</strong></p>
<p>请求拦截器 <pre class="language-js" data-language="js"><code class="language-js">axios<span class="token punctuation">.</span>interceptors<span class="token punctuation">.</span>request<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">config</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    <span class="token comment">// 成功的处理</span>
    <span class="token keyword">return</span> config<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    <span class="token comment">// 失败的处理</span>
    <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></p>
<ul>
<li><strong>参数</strong> 请求拦截器有两个回调函数
<ul>
<li>如果成功，那么执行第一个回调函数，这个回调函数的参数是上一个Promise发来的config</li>
<li>如果失败，那么执行第二个回调函数，这个回调函数的参数是错误的reject</li>
<li>如果某个回调函数判定当前数据有误，返回Promise.reject</li>
<li>如果某个回调函数判定当前数据正确，返回Promise.resolve (直接return
config，必须有config用于下一个函数调用)</li>
</ul></li>
<li><strong>注意</strong>
<ul>
<li>这个函数包含了两个回调函数，成功后要运行的函数与失败后要运行的函数,但是什么是成功与失败?</li>
<li>如果学过Promise可以看出来这两个函数很像是Promise.then().catch()</li>
<li>实际上就是这样的,请求拦截器是Axios的Promise链上的一个元素,所以在一个请求的Promise链上可以存在多个请求拦截器或者响应拦截器</li>
<li>某一个请求拦截器的第一个回调函数(也就是我们所说的"成功"函数)，会被调用当且仅当Promise链上的上一个元素得到了Resolve的<strong>返回值</strong></li>
<li>某一个请求拦截器的第二个回调函数(也就是我们所说的"失败"函数)，会被调用当且仅当Promise链上的上一个元素得到了Reject的<strong>返回值</strong></li>
<li>第一个<strong>被执行的</strong>的请求器是直接调用第一个回调函数，也就是有如下链
<ul>
<li>Axios的请求Promise链上一个环节调用第一个被执行的请求拦截器的第一个回调函数(成功的)，如果判断结果是可以执行(也就是返回处理后的config)那么相当于得到了resolve,如果有误则返回Promise.reject()</li>
<li>下一个被执行的请求拦截器查看上一个的返回值，如果是reject执行他的第二个回调函数，否则执行第一个</li>
<li>执行到最后一个拦截器之后，如果返回是resolve那么Axios发送请求，否则直接执行第一个响应拦截器的第二个回调函数(失败的)</li>
</ul></li>
<li>由于是Promise的调用，完全存在这种情况，有两个请求拦截器
<ul>
<li>第一个拦截器第一个回调函数直接返回reject</li>
<li>第二个拦截器第二个回调函数直接返回resolve(也就是return一个config对象)</li>
<li>正常发送请求</li>
</ul></li>
</ul></li>
</ul>
<p>响应拦截器 <pre class="language-js" data-language="js"><code class="language-js">axios<span class="token punctuation">.</span>interceptors<span class="token punctuation">.</span>response<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    <span class="token comment">// 成功的处理</span>
    <span class="token keyword">return</span> response<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    <span class="token comment">// 失败的处理</span>
    <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre> - <strong>参数</strong>
响应拦截器有两个回调函数 -
如果成功，那么执行第一个回调函数，这个回调函数的参数是上一个Promise发来的自定义对象，这个对象会作为响应的结果返回
- 如果失败，那么执行第二个回调函数，这个回调函数的参数是错误的reject -
如果某个回调函数判定当前数据有误，返回Promise.reject -
如果某个回调函数判定当前数据正确，返回Promise.resolve (直接return
想返回的数据，可以与response有很大区别)</p>
<p><strong>注意</strong>： -
如果代码中存在多个请求拦截器或者响应拦截器，那么会代码中出现的次序<strong>逆序</strong>执行请求拦截器/<strong>顺序</strong>执行响应拦截器,
例如 <pre class="language-js" data-language="js"><code class="language-js">axios<span class="token punctuation">.</span>interceptors<span class="token punctuation">.</span>request<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">config</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"请求拦截器1 成功"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> config<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"请求拦截器1 失败"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> Promise<span class="token punctuation">.</span>reject<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

axios<span class="token punctuation">.</span>interceptors<span class="token punctuation">.</span>request<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">config</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"请求拦截器2 成功"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> config<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"请求拦截器2 失败"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> Promise<span class="token punctuation">.</span>reject<span class="token punctuation">;</span>

axios<span class="token punctuation">.</span>interceptors<span class="token punctuation">.</span>response<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"响应拦截器1 成功"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> response<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"响应拦截器1 失败"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

axios<span class="token punctuation">.</span>interceptors<span class="token punctuation">.</span>response<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"响应拦截器2 成功"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> response<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"响应拦截器2 失败"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">axios</span><span class="token punctuation">(</span><span class="token operator">...</span><span class="token punctuation">)</span></code></pre> 我们看到的结果将是 <pre class="language-none"><code class="language-none">请求拦截器2 成功
请求拦截器1 成功
响应拦截器1 成功
响应拦截器2 成功</code></pre></p>
<ul>
<li>我们再在代码中加入奇怪的东西，熟练Promise链 <pre class="language-js" data-language="js"><code class="language-js"><span class="token comment">// 请求部分</span>
axios<span class="token punctuation">.</span>interceptors<span class="token punctuation">.</span>request<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">config</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"请求拦截器1 成功函数进入"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// 经过一系列检查我觉得他没问题，给他正常通过</span>
    <span class="token comment">// 这是最后一个请求拦截器，一旦通过就正常发送请求了</span>
    <span class="token keyword">return</span> config                       <span class="token comment">// [ Falg1 ]</span>
    <span class="token comment">// 这是最后一个请求拦截器，一旦失败就不请求直接进入失败拦截器了</span>
    <span class="token comment">// return Promise.reject(config);   // [ Falg2 ]</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"请求拦截器1 失败函数进入"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// 这是最后一个请求拦截器，一旦失败就不请求直接进入失败拦截器了</span>
    <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

axios<span class="token punctuation">.</span>interceptors<span class="token punctuation">.</span>request<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">config</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"请求拦截器2 成功函数进入"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> config<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"请求拦截器2 失败函数进入"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// 虽然上一步拒绝了，但是我故意让他变为成功,我用了完整的写法</span>
    <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

axios<span class="token punctuation">.</span>interceptors<span class="token punctuation">.</span>request<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">config</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"请求拦截器3 成功函数进入"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// 经过一系列检查我拒绝了这个config，在拒绝信息写入config方便变化，实际应该写错误信息</span>
    <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span>config<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"请求拦截器3 失败函数进入"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 响应部分</span>
axios<span class="token punctuation">.</span>interceptors<span class="token punctuation">.</span>response<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"响应拦截器1 成功函数进入"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// 收到了数据并且直接返回了</span>
    <span class="token keyword">return</span> response<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"响应拦截器1 失败函数进入"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// 收到了请求拦截器的拒绝，跳过发送，直接到这里，返回拒绝</span>
    <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

axios<span class="token punctuation">.</span>interceptors<span class="token punctuation">.</span>response<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"响应拦截器2 成功函数进入"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// 先看看数据</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>response<span class="token punctuation">)</span>
    <span class="token comment">// 这是个奇怪的函数会反转结果</span>
    <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span>response<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"响应拦截器2 失败函数进入"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// 先看看数据</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span>
    <span class="token comment">// 这是个奇怪的函数会反转结果</span>
    <span class="token keyword">return</span> error<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

axios<span class="token punctuation">.</span>interceptors<span class="token punctuation">.</span>response<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"响应拦截器3 成功函数进入"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// 既然成功了，那让我们返回响应的数据，但是返回这么多又没啥用，我们直接返回一个Happy吧</span>
    <span class="token keyword">return</span> <span class="token string">"Happy"</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"响应拦截器3 失败函数进入"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// 既然失败了，那让我们返回失败的信息，但是返回这么多又没啥用，我们直接返回一个Sad吧</span>
    <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span><span class="token string">"Sad"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

axios<span class="token punctuation">.</span><span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span>
    <span class="token literal-property property">method</span>  <span class="token operator">:</span>   <span class="token string">"GET"</span><span class="token punctuation">,</span>
    <span class="token literal-property property">url</span>     <span class="token operator">:</span>   <span class="token string">"http://127.0.0.1:3000/posts"</span><span class="token punctuation">,</span>      <span class="token comment">// 是前面json-server的服务</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">d</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"请求成功了"</span><span class="token punctuation">,</span>d<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"请求失败了"</span><span class="token punctuation">,</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span></code></pre>
尝试执行函数并理解Promise链的调用关系，之后尝试注释掉<code>[ Flag1 ]</code>行，取消注释<code>[ Flag2 ]</code>行，查看结果</li>
</ul>
<p>结果1 <pre class="language-none"><code class="language-none">请求拦截器3 成功函数进入
请求拦截器2 失败函数进入
请求拦截器1 成功函数进入
响应拦截器1 成功函数进入
响应拦截器2 成功函数进入
&#123;data: Array(8), status: 200, statusText: &quot;OK&quot;, headers: &#123;…&#125;, config: &#123;…&#125;, …&#125;
响应拦截器3 失败函数进入
请求失败了 Sad</code></pre> 结果2 <pre class="language-none"><code class="language-none">请求拦截器3 成功函数进入
请求拦截器2 失败函数进入
请求拦截器1 成功函数进入
响应拦截器1 失败函数进入
响应拦截器2 失败函数进入
&#123;url: &quot;http:&#x2F;&#x2F;127.0.0.1:3000&#x2F;posts&quot;, method: &quot;get&quot;, headers: &#123;…&#125;, transformRequest: Array(1), transformResponse: Array(1), …&#125;
响应拦截器3 成功函数进入
请求成功了 Happy</code></pre></p>
<ul>
<li>拦截器与transformXXX的执行顺序是
请求拦截器,<code>transformRequest</code>,<code>transformResponse</code>,响应拦截器,
对上面的代码稍加修改接可以看到 <pre class="language-js" data-language="js"><code class="language-js">axios<span class="token punctuation">.</span>interceptors<span class="token punctuation">.</span>request<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">config</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"请求拦截器 成功"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> config<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"请求拦截器 失败"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

axios<span class="token punctuation">.</span>interceptors<span class="token punctuation">.</span>response<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"响应拦截器 成功"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> response<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"响应拦截器 失败"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

axios<span class="token punctuation">.</span><span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span>
    <span class="token literal-property property">method</span>  <span class="token operator">:</span>   <span class="token string">"GET"</span><span class="token punctuation">,</span>
    <span class="token literal-property property">url</span>     <span class="token operator">:</span>   <span class="token string">"http://127.0.0.1:3000/posts"</span><span class="token punctuation">,</span>
    <span class="token literal-property property">transformRequest</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">(</span><span class="token parameter">d</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"TFReq"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">return</span> d<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
    <span class="token literal-property property">transformResponse</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">(</span><span class="token parameter">d</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"TFRes"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">return</span> d<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">]</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">d</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>d<span class="token punctuation">.</span>data<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span></code></pre> 结果是 <pre class="language-none"><code class="language-none">请求拦截器 成功
TFReq
TFRes
响应拦截器 成功
&#x2F;&#x2F; 返回的数据</code></pre></li>
</ul>
<h3 id="取消请求">取消请求</h3>
<p>非常简单 <pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> cancelFlag <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>  <span class="token comment">// 请求取消函数</span>
<span class="token comment">// 请求按钮</span>
btn_req<span class="token punctuation">.</span><span class="token function-variable function">onclick</span><span class="token operator">=</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    <span class="token function">axios</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span>
        <span class="token literal-property property">method</span>  <span class="token operator">:</span>   <span class="token string">"GET"</span><span class="token punctuation">,</span>
        <span class="token literal-property property">url</span>     <span class="token operator">:</span>   <span class="token string">"http://127.0.0.1:3000/posts"</span><span class="token punctuation">,</span>
        <span class="token comment">// 多加入一行，cancelTocken是一个回调函数，对象是axios的新取消，设置请求取消函数</span>
        <span class="token literal-property property">cancelToken</span><span class="token operator">:</span> <span class="token keyword">new</span> <span class="token class-name">axios<span class="token punctuation">.</span>CancelToken</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">c</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
            cancelFlag <span class="token operator">=</span> c<span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"OK"</span><span class="token punctuation">)</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span>

<span class="token comment">// 取消请求按钮</span>
btn_can<span class="token punctuation">.</span><span class="token function-variable function">onclick</span><span class="token operator">=</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    <span class="token function">cancelFlag</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Cancel"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span></code></pre> 设置json-server响应延迟2000ms <pre class="language-js" data-language="js"><code class="language-js">json<span class="token operator">-</span>server <span class="token operator">--</span>watch db<span class="token punctuation">.</span>json <span class="token operator">--</span>delay <span class="token number">2000</span></code></pre>
## Axios源码分析</p>
<p>直接在<code>./node_modules/axios</code>获取Axios源码，删除无用文件(例如证书)</p>
<h3 id="目录结构">目录结构</h3>
<pre class="language-none"><code class="language-none">.
├── dist                            &#x2F;&#x2F; 打包后的文件
│   ├── axios.js                    &#x2F;&#x2F; 未压缩的
│   ├── axios.map                   &#x2F;&#x2F; 对应文件
│   ├── axios.min.js                &#x2F;&#x2F; 压缩后的
│   └── axios.min.map               &#x2F;&#x2F; 对应文件
├── index.d.ts                      &#x2F;&#x2F; ts使用版本文件             
├── index.js                        &#x2F;&#x2F; 包入口文件
├── lib                             &#x2F;&#x2F; 核心目录
│   ├── adapters                    &#x2F;&#x2F; 自定义请求的是适配器
│   │   ├── http.js                 &#x2F;&#x2F; 用于在Node中发送请求的适配器
│   │   └── xhr.js                  &#x2F;&#x2F; 用于在浏览器中发送Ajax的适配器
│   ├── axios.js                    &#x2F;&#x2F; 入口文件
│   ├── cancel                      &#x2F;&#x2F; 与取消相关文件
│   │   ├── Cancel.js               &#x2F;&#x2F; Cancel构造函数
│   │   ├── CancelToken.js          &#x2F;&#x2F; 创建取消请求的构造函数
│   │   └── isCancel.js             &#x2F;&#x2F; 判断某一个值是不是由取消产生的结果
│   ├── core                        &#x2F;&#x2F; 核心功能文件 
│   │   ├── Axios.js                &#x2F;&#x2F; Axios的构造函数文件
│   │   ├── buildFullPath.js        &#x2F;&#x2F; 构造完整URL的文件
│   │   ├── createError.js          &#x2F;&#x2F; 创建Error对象
│   │   ├── dispatchRequest.js      &#x2F;&#x2F; 发送请求
│   │   ├── enhanceError.js         &#x2F;&#x2F; 更新错误对象
│   │   ├── InterceptorManager.js   &#x2F;&#x2F; 拦截器管理器构造函数
│   │   ├── mergeConfig.js          &#x2F;&#x2F; 合并配置的文件
│   │   ├── settle.js               &#x2F;&#x2F; 根据http响应状态码更新Promise状态
│   │   └── transformData.js        &#x2F;&#x2F; 对结果格式化
│   ├── defaults.js                 &#x2F;&#x2F; 默认配置文件
│   ├── helpers                     &#x2F;&#x2F; 功能函数
│   │   ├── bind.js                 &#x2F;&#x2F; 用于创建函数，修改函数允许时this指向
│   │   ├── buildURL.js             &#x2F;&#x2F; 构造url,加入参数(例如get的parame)
│   │   ├── combineURLs.js          &#x2F;&#x2F; 合并url
│   │   ├── cookies.js              &#x2F;&#x2F; 操作cookie
│   │   ├── deprecatedMethod.js     &#x2F;&#x2F; 如果使用了某个过时方法在控制台waring
│   │   ├── isAbsoluteURL.js        &#x2F;&#x2F; 判断url为绝对路径
│   │   ├── isAxiosError.js         &#x2F;&#x2F; 判断url正误
│   │   ├── isURLSameOrigin.js      &#x2F;&#x2F; 判断url同源
│   │   ├── normalizeHeaderName.js  &#x2F;&#x2F; 统一请求头，例如小写字母转大写
│   │   ├── parseHeaders.js
│   │   └── spread.js               &#x2F;&#x2F; 对请求进行批量处理
│   └── utils.js                    &#x2F;&#x2F; 比较杂的工具函数文件
└── package.json</code></pre>
<h3
id="实现axios使得既可以axios也可以axios.xx">实现axios,使得既可以axios()也可以axios.xx()</h3>
<p>在发送请求的时候我们既可以<code>axios(...)</code>,也可以使用<code>axios.get()</code>，也就是说axios既是一个函数，也是一个对象。这点与jQuery相似，即可<code>$()</code>,也可以<code>$.XX()</code>，实际上他们实现的方法都是相同的</p>
<p>Axios包的入口文件是<code>./index.js</code> <pre class="language-js" data-language="js"><code class="language-js">module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'./lib/axios'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
我们看<code>./lib/axios</code> <pre class="language-js" data-language="js"><code class="language-js"><span class="token string">'use strict'</span><span class="token punctuation">;</span>               <span class="token comment">// 启动严格模式</span>

<span class="token keyword">var</span> utils <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'./utils'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>         <span class="token comment">// 导入工具函数</span>
<span class="token keyword">var</span> bind <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'./helpers/bind'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token comment">// 导入bind</span>
<span class="token keyword">var</span> Axios <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'./core/Axios'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">// 导入Axios对象</span>
<span class="token keyword">var</span> mergeConfig <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'./core/mergeConfig'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">// 导入合并配置文件</span>
<span class="token keyword">var</span> defaults <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'./defaults'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>               <span class="token comment">// 导入默认配置</span>

<span class="token comment">/**
 * 创建一个类axios的函数
 * 注意他返回的不是Axios的实例
 * 他的目的是返回一个duanzi = axios.creat()中和duanzi一样的对象
 *
 * @参数 axios的默认配置参数，也就是写 duanzi = axios.config(&#123;...&#125;)的时候()中的config
 * @返回 类似axios对象
 */</span>
<span class="token keyword">function</span> <span class="token function">createInstance</span><span class="token punctuation">(</span><span class="token parameter">defaultConfig</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
  <span class="token comment">// ! Context是一个Axios对象</span>
  <span class="token keyword">var</span> context <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Axios</span><span class="token punctuation">(</span>defaultConfig<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token comment">// bind是函数绑定的工具函数，在./helpers/bind，可以绑定函数，修改this</span>
  <span class="token comment">// 这句话的意思相当于是instance=Axios.prototype.request instance运行时候this是context</span>
  <span class="token comment">// Axios.prototype.request是用来发送请求的，这个函数调用dispatchRequest.js</span>
  <span class="token comment">// dispatchRequest.js 调用xhr/http.js进行请求</span>
  <span class="token comment">// ! instance目前是一个函数, 只有Request</span>
  <span class="token keyword">var</span> instance <span class="token operator">=</span> <span class="token function">bind</span><span class="token punctuation">(</span><span class="token class-name">Axios</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>request<span class="token punctuation">,</span> context<span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">// utils位于./utils，可以将对象的方法进行复制</span>
  <span class="token comment">// 实际上就是执行了一次遍历进行深拷贝</span>
  <span class="token comment">// 第三个参数是某个被拷贝的参数是函数，要把函数运行的this修改成context,不填就不改</span>
  <span class="token comment">// ! instance目前有了context的函数和Request函数</span>
  utils<span class="token punctuation">.</span><span class="token function">extend</span><span class="token punctuation">(</span>instance<span class="token punctuation">,</span> <span class="token class-name">Axios</span><span class="token punctuation">.</span>prototype<span class="token punctuation">,</span> context<span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">// ! instance绑定上context的对象</span>
  utils<span class="token punctuation">.</span><span class="token function">extend</span><span class="token punctuation">(</span>instance<span class="token punctuation">,</span> context<span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">// 相当于instance = Axios对象+请求函数</span>
  <span class="token keyword">return</span> instance<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>

<span class="token comment">// 获得一个axios</span>
<span class="token keyword">var</span> axios <span class="token operator">=</span> <span class="token function">createInstance</span><span class="token punctuation">(</span>defaults<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">/**
 * 下面这些就是为axios绑定Axios没有的方法
 * 平时我们创建一个 duanzi = axios.creat() 获得的就够就没有这些方法
 */</span>

<span class="token comment">// 绑定Axios方法</span>
axios<span class="token punctuation">.</span>Axios <span class="token operator">=</span> Axios<span class="token punctuation">;</span>

<span class="token comment">// 用于创建新实例的方法</span>
axios<span class="token punctuation">.</span><span class="token function-variable function">create</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token function">create</span><span class="token punctuation">(</span><span class="token parameter">instanceConfig</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
  <span class="token keyword">return</span> <span class="token function">createInstance</span><span class="token punctuation">(</span><span class="token function">mergeConfig</span><span class="token punctuation">(</span>axios<span class="token punctuation">.</span>defaults<span class="token punctuation">,</span> instanceConfig<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span>

<span class="token comment">// 绑定方法</span>
axios<span class="token punctuation">.</span>Cancel <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'./cancel/Cancel'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
axios<span class="token punctuation">.</span>CancelToken <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'./cancel/CancelToken'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
axios<span class="token punctuation">.</span>isCancel <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'./cancel/isCancel'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

axios<span class="token punctuation">.</span><span class="token function-variable function">all</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token function">all</span><span class="token punctuation">(</span><span class="token parameter">promises</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
  <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">all</span><span class="token punctuation">(</span>promises<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
axios<span class="token punctuation">.</span>spread <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'./helpers/spread'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

axios<span class="token punctuation">.</span>isAxiosError <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'./helpers/isAxiosError'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 导出axios</span>
module<span class="token punctuation">.</span>exports <span class="token operator">=</span> axios<span class="token punctuation">;</span>

module<span class="token punctuation">.</span>exports<span class="token punctuation">.</span>default <span class="token operator">=</span> axios<span class="token punctuation">;</span></code></pre></p>
<p>很不错的创建工具函数的方法，我有Axios对象，我希望构造一个axios变量，本身是一个函数，也是一个对象，作为函数可以快速实现Axios的某个功能，作为对象可以包含定义一系列不常用的Axios方法，可以创建一个新的实例，做普通实例没有的方法，这个与jQuery的<code>$</code>原理是一样的</p>
<ul>
<li>定义好Axios对象</li>
<li>创建一个axios变量，默认值就是默认配置下的Axios实例</li>
<li>完善结构，将全局暴露的函数导出为axios的属性</li>
</ul>
<p><strong>JSDoc注释</strong></p>
<p>源码中注释是这么写的 <pre class="language-js" data-language="js"><code class="language-js"><span class="token comment">/**
 * Create an instance of Axios
 *
 * @param &#123;Object&#125; defaultConfig The default config for the instance
 * @return &#123;Axios&#125; A new instance of Axios
 */</span></code></pre>
我们点击一个@的时候可以进行跳转，这是JSDoc注释规范，</p>
<h3 id="axios类的实现">Axios类的实现</h3>
<p>看./lib/core/Axios.js文件(可以先看./InterceptorManager.js)
<pre class="language-js" data-language="js"><code class="language-js"><span class="token string">'use strict'</span><span class="token punctuation">;</span>                       <span class="token comment">// 严格模式</span>

<span class="token keyword">var</span> utils <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'./../utils'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// 引用工具函数</span>
<span class="token keyword">var</span> buildURL <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'../helpers/buildURL'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>            <span class="token comment">// 构建url的模块</span>
<span class="token keyword">var</span> InterceptorManager <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'./InterceptorManager'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 拦截器管理器模块</span>
<span class="token keyword">var</span> dispatchRequest <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'./dispatchRequest'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>       <span class="token comment">// 发送请求模块</span>
<span class="token keyword">var</span> mergeConfig <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'./mergeConfig'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>               <span class="token comment">// 默认配置模块(例如默认method是get就是来自这里)</span>

<span class="token comment">/**
 * Axios的实现
 *
 * @param &#123;Object&#125; instanceConfig 传入config,例如duanzi = axios.creat(config)的config就是用在了这里
 */</span>
<span class="token keyword">function</span> <span class="token function">Axios</span><span class="token punctuation">(</span><span class="token parameter">instanceConfig</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span>defaults <span class="token operator">=</span> instanceConfig<span class="token punctuation">;</span>       <span class="token comment">// 用来放配置文件</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span>interceptors <span class="token operator">=</span> <span class="token punctuation">&#123;</span>                 <span class="token comment">// 两个拦截器，分别是两个拦截器管理器对象</span>
    <span class="token literal-property property">request</span><span class="token operator">:</span> <span class="token keyword">new</span> <span class="token class-name">InterceptorManager</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token literal-property property">response</span><span class="token operator">:</span> <span class="token keyword">new</span> <span class="token class-name">InterceptorManager</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>

<span class="token comment">/**
 * 发送请求的模块
 *
 * @param &#123;Object&#125; config 这是例如axios.get(&#123;config&#125;)的时候的config
 */</span>
<span class="token class-name">Axios</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">request</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token parameter">config</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
  <span class="token comment">// 存在两种情况的请求，一种是</span>
  <span class="token comment">//    axios(&#123;config&#125;)</span>
  <span class="token comment">//    axios.get("http://127.0.0.1",&#123;config&#125;)</span>
  <span class="token comment">// 我们要处理两种情况</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> config <span class="token operator">===</span> <span class="token string">'string'</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    <span class="token comment">// 处理第二种情况</span>
    config <span class="token operator">=</span> arguments<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">||</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
    config<span class="token punctuation">.</span>url <span class="token operator">=</span> arguments<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
  <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>
    <span class="token comment">// 方式不传参 config=null</span>
    config <span class="token operator">=</span> config <span class="token operator">||</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
  <span class="token punctuation">&#125;</span>

  <span class="token comment">// 将config与axios的默认/自定义实例的config合并</span>
  config <span class="token operator">=</span> <span class="token function">mergeConfig</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>defaults<span class="token punctuation">,</span> config<span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">// 填写请求类型</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>config<span class="token punctuation">.</span>method<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    <span class="token comment">// 如果config有指定就格式化一下</span>
    config<span class="token punctuation">.</span>method <span class="token operator">=</span> config<span class="token punctuation">.</span>method<span class="token punctuation">.</span><span class="token function">toLowerCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>defaults<span class="token punctuation">.</span>method<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    <span class="token comment">// 如果config没有指定，但是axios实例指定了，例如在duanzi = axios.creat(&#123;method="get"&#125;)</span>
    config<span class="token punctuation">.</span>method <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>defaults<span class="token punctuation">.</span>method<span class="token punctuation">.</span><span class="token function">toLowerCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>
    <span class="token comment">// 否则默认get</span>
    config<span class="token punctuation">.</span>method <span class="token operator">=</span> <span class="token string">'get'</span><span class="token punctuation">;</span>
  <span class="token punctuation">&#125;</span>

  <span class="token comment">/**
   * 构建拦截器串
   * 使用一个数组
   * 第一个参数是一个发送请求的返回Promise的函数，来自./dispatchRequest.js
   * 后面留空用来候补，暂时不要管这个反着的顺序
   */</span>
  <span class="token comment">// 注意这里的undefine是必须的，我们知道这个chain中的函数都是成对出现的</span>
  <span class="token comment">// [请求拦截器2.resolve,请求拦截器2.reject,请求拦截器1.resolve,请求拦截器1.reject,请求发送函数,undefine,响应拦截器1.resolve,响应拦截器1.reject,响应拦截器2.resolve,响应拦截器2.reject]</span>
  <span class="token comment">// 如果请求1 resolve了，会跳到请求发送函数，如果请求1 reject了，那么下一个是undefine，undefine无法执行就会掷出一个error到下一个catch，也就是相应拦截器1 reject</span>
  <span class="token comment">// 一定会跳转到undefine是因为执行的时候是promise = promise.then(chain.shift(), chain.shift());执行的</span>
  <span class="token keyword">var</span> chain <span class="token operator">=</span> <span class="token punctuation">[</span>dispatchRequest<span class="token punctuation">,</span> <span class="token keyword">undefined</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
  <span class="token comment">// 构建一个resolve的Promise用来开启Promise链，config是resolve的结果，传参到链</span>
  <span class="token keyword">var</span> promise <span class="token operator">=</span> Promise<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span>config<span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">/** 
   * 遍历请求拦截器管理器
   * 是一个，管理器是一个对象(伪数组)，自己封装了forEach方法(伪数组本不可以用forEach),封装了use方法
   * 管理器伪数组中的元素是对象，每个对象有两个子对象
   * &#123;
   *    fulfilled: fulfilled,
   *    rejected: rejected
   * &#125;
   * 分别是axios.interceptors.request.use()的两个回调函数
   */</span> 
  <span class="token keyword">this</span><span class="token punctuation">.</span>interceptors<span class="token punctuation">.</span>request<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token function">unshiftRequestInterceptors</span><span class="token punctuation">(</span><span class="token parameter">interceptor</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    <span class="token comment">// 数组的unshift方法是向前添加一个元素</span>
    chain<span class="token punctuation">.</span><span class="token function">unshift</span><span class="token punctuation">(</span>interceptor<span class="token punctuation">.</span>fulfilled<span class="token punctuation">,</span> interceptor<span class="token punctuation">.</span>rejected<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token comment">// 遍历响应器拦截器</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span>interceptors<span class="token punctuation">.</span>response<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token function">pushResponseInterceptors</span><span class="token punctuation">(</span><span class="token parameter">interceptor</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    chain<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>interceptor<span class="token punctuation">.</span>fulfilled<span class="token punctuation">,</span> interceptor<span class="token punctuation">.</span>rejected<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">// 执行这个Promise链</span>
  <span class="token keyword">while</span> <span class="token punctuation">(</span>chain<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    promise <span class="token operator">=</span> promise<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>chain<span class="token punctuation">.</span><span class="token function">shift</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> chain<span class="token punctuation">.</span><span class="token function">shift</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">&#125;</span>
  
  <span class="token keyword">return</span> promise<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span>

<span class="token class-name">Axios</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">getUri</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token function">getUri</span><span class="token punctuation">(</span><span class="token parameter">config</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
  config <span class="token operator">=</span> <span class="token function">mergeConfig</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>defaults<span class="token punctuation">,</span> config<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">return</span> <span class="token function">buildURL</span><span class="token punctuation">(</span>config<span class="token punctuation">.</span>url<span class="token punctuation">,</span> config<span class="token punctuation">.</span>params<span class="token punctuation">,</span> config<span class="token punctuation">.</span>paramsSerializer<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^\?</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">,</span> <span class="token string">''</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span>

<span class="token comment">// 定义axios.get...函数, 不包含请求体的协议</span>
utils<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">'delete'</span><span class="token punctuation">,</span> <span class="token string">'get'</span><span class="token punctuation">,</span> <span class="token string">'head'</span><span class="token punctuation">,</span> <span class="token string">'options'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token function">forEachMethodNoData</span><span class="token punctuation">(</span><span class="token parameter">method</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
  <span class="token class-name">Axios</span><span class="token punctuation">.</span>prototype<span class="token punctuation">[</span>method<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">url<span class="token punctuation">,</span> config</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">request</span><span class="token punctuation">(</span><span class="token function">mergeConfig</span><span class="token punctuation">(</span>config <span class="token operator">||</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">,</span> <span class="token punctuation">&#123;</span>
      <span class="token literal-property property">method</span><span class="token operator">:</span> method<span class="token punctuation">,</span>
      <span class="token literal-property property">url</span><span class="token operator">:</span> url<span class="token punctuation">,</span>
      <span class="token literal-property property">data</span><span class="token operator">:</span> <span class="token punctuation">(</span>config <span class="token operator">||</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">.</span>data
    <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 定义axios.post...函数，包含请求体的协议</span>
utils<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">'post'</span><span class="token punctuation">,</span> <span class="token string">'put'</span><span class="token punctuation">,</span> <span class="token string">'patch'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token function">forEachMethodWithData</span><span class="token punctuation">(</span><span class="token parameter">method</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
  <span class="token class-name">Axios</span><span class="token punctuation">.</span>prototype<span class="token punctuation">[</span>method<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">url<span class="token punctuation">,</span> data<span class="token punctuation">,</span> config</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">request</span><span class="token punctuation">(</span><span class="token function">mergeConfig</span><span class="token punctuation">(</span>config <span class="token operator">||</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">,</span> <span class="token punctuation">&#123;</span>
      <span class="token literal-property property">method</span><span class="token operator">:</span> method<span class="token punctuation">,</span>
      <span class="token literal-property property">url</span><span class="token operator">:</span> url<span class="token punctuation">,</span>
      <span class="token literal-property property">data</span><span class="token operator">:</span> data
    <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

module<span class="token punctuation">.</span>exports <span class="token operator">=</span> Axios<span class="token punctuation">;</span></code></pre></p>
<p>注意Promise链的实现 <pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">var</span> chain <span class="token operator">=</span> <span class="token punctuation">[</span>dispatchRequest<span class="token punctuation">,</span> <span class="token keyword">undefined</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> promise <span class="token operator">=</span> Promise<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span>config<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">this</span><span class="token punctuation">.</span>interceptors<span class="token punctuation">.</span>request<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token function">unshiftRequestInterceptors</span><span class="token punctuation">(</span><span class="token parameter">interceptor</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
  chain<span class="token punctuation">.</span><span class="token function">unshift</span><span class="token punctuation">(</span>interceptor<span class="token punctuation">.</span>fulfilled<span class="token punctuation">,</span> interceptor<span class="token punctuation">.</span>rejected<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>interceptors<span class="token punctuation">.</span>response<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token function">pushResponseInterceptors</span><span class="token punctuation">(</span><span class="token parameter">interceptor</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
  chain<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>interceptor<span class="token punctuation">.</span>fulfilled<span class="token punctuation">,</span> interceptor<span class="token punctuation">.</span>rejected<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">while</span> <span class="token punctuation">(</span>chain<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
  promise <span class="token operator">=</span> promise<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>chain<span class="token punctuation">.</span><span class="token function">shift</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> chain<span class="token punctuation">.</span><span class="token function">shift</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span></code></pre></p>
<h3 id="手写一个简易版的axios">手写一个简易版的axios</h3>
<pre class="language-js" data-language="js"><code class="language-js"><span class="token comment">// 封装工具函数 对应的是 ./lib/utils.js</span>
<span class="token keyword">function</span> <span class="token function">Utiles</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
<span class="token comment">// 合并配置文件函数 对应 merge()</span>
<span class="token class-name">Utiles</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">mergeConfig</span><span class="token operator">=</span><span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span>arg</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span>arg<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token keyword">return</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
    arg<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token operator">=</span><span class="token punctuation">(</span><span class="token keyword">typeof</span><span class="token punctuation">(</span>arg<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">==</span><span class="token string">'string'</span><span class="token punctuation">)</span><span class="token operator">?</span><span class="token punctuation">&#123;</span><span class="token string-property property">"url"</span><span class="token operator">:</span>arg<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">&#125;</span><span class="token operator">:</span>arg<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token keyword">let</span> config <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
    arg<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">d<span class="token punctuation">,</span>i</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
        <span class="token keyword">for</span><span class="token punctuation">(</span>dd <span class="token keyword">in</span> d<span class="token punctuation">)</span>
            config<span class="token punctuation">[</span>dd<span class="token punctuation">]</span><span class="token operator">=</span>d<span class="token punctuation">[</span>dd<span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> config<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>

<span class="token keyword">let</span> utiles<span class="token operator">=</span><span class="token keyword">new</span> <span class="token class-name">Utiles</span><span class="token punctuation">;</span>

<span class="token comment">// Axios部分 ./lib/core/Axios.js</span>
<span class="token keyword">function</span> <span class="token function">Axios</span><span class="token punctuation">(</span><span class="token parameter">config</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    <span class="token comment">// 配置文件的默认设置，例如默认mothod是get,加了一个是测试用的，对应./lib/defaults.js</span>
    <span class="token comment">// 这个method与人家实现不同</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>defaultConfig <span class="token operator">=</span> <span class="token punctuation">&#123;</span>
        <span class="token string-property property">"globalDefault"</span><span class="token operator">:</span> <span class="token string">"I'm Axios default setting"</span><span class="token punctuation">,</span>
        <span class="token string-property property">"method"</span><span class="token operator">:</span> <span class="token string">"GET"</span>
    <span class="token punctuation">&#125;</span>
    <span class="token comment">// 某一个方法的默认配置</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>methodDefaultConfig <span class="token operator">=</span> <span class="token punctuation">&#123;</span>
        <span class="token string-property property">"GET"</span><span class="token operator">:</span><span class="token punctuation">&#123;</span><span class="token string-property property">"defaultMethodConfig"</span><span class="token operator">:</span><span class="token string">"GET"</span><span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
        <span class="token string-property property">"POST"</span><span class="token operator">:</span><span class="token punctuation">&#123;</span><span class="token string-property property">"defaultMethodConfig"</span><span class="token operator">:</span><span class="token string">"POST"</span><span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
        <span class="token string-property property">"PUT"</span><span class="token operator">:</span><span class="token punctuation">&#123;</span><span class="token string-property property">"defaultMethodConfig"</span><span class="token operator">:</span><span class="token string">"PUT"</span><span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
        <span class="token string-property property">"DELETE"</span><span class="token operator">:</span><span class="token punctuation">&#123;</span><span class="token string-property property">"defaultMethodConfig"</span><span class="token operator">:</span><span class="token string">"DELETE"</span><span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
    <span class="token punctuation">&#125;</span>
    <span class="token comment">// 实例的配置</span>
    config <span class="token operator">=</span> config<span class="token operator">||</span><span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
    <span class="token comment">// 请求配置就是实例的配置</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>ReqConfig <span class="token operator">=</span> config<span class="token punctuation">;</span>
    <span class="token comment">// 两个拦截器</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>interceptor<span class="token operator">=</span><span class="token punctuation">&#123;</span>
        <span class="token comment">// TODO</span>
        <span class="token literal-property property">reqInterceptor</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
        <span class="token literal-property property">resInterceptor</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>

<span class="token comment">// 执行请求拦截器链</span>
<span class="token class-name">Axios</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">reqinterceptorChain</span><span class="token operator">=</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">chrInt</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    <span class="token keyword">let</span> len <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>interceptor<span class="token punctuation">.</span>reqInterceptor<span class="token punctuation">.</span>length<span class="token punctuation">;</span>
    <span class="token comment">// 如果没有指定就用默认配置resolve开始请求</span>
    chrInt <span class="token operator">=</span> chrInt <span class="token operator">||</span> Promise<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>ReqConfig<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">while</span><span class="token punctuation">(</span>len<span class="token operator">--</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
        <span class="token comment">// 防止len作为闭包传输导致的len--修改len</span>
        <span class="token keyword">let</span> tmp <span class="token operator">=</span> len<span class="token punctuation">;</span>
        <span class="token comment">// Promise链</span>
        chrInt <span class="token operator">=</span> chrInt<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>
            <span class="token parameter">d</span><span class="token operator">=></span><span class="token keyword">this</span><span class="token punctuation">.</span>interceptor<span class="token punctuation">.</span>reqInterceptor<span class="token punctuation">[</span>tmp<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">(</span>d<span class="token punctuation">)</span><span class="token punctuation">,</span>
            <span class="token parameter">e</span><span class="token operator">=></span><span class="token keyword">this</span><span class="token punctuation">.</span>interceptor<span class="token punctuation">.</span>reqInterceptor<span class="token punctuation">[</span>tmp<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span>
        <span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
    <span class="token keyword">return</span> chrInt<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>

<span class="token class-name">Axios</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">resinterceptorChain</span><span class="token operator">=</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">chrInt</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    <span class="token keyword">let</span> len <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>interceptor<span class="token punctuation">.</span>reqInterceptor<span class="token punctuation">.</span>length<span class="token punctuation">;</span>
    <span class="token comment">// 上面没给请求成功还是失败了</span>
    chrInt <span class="token operator">=</span> chrInt <span class="token operator">||</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span><span class="token string">"上头没给传参数"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i<span class="token operator">&lt;</span>len<span class="token punctuation">;</span>i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
        <span class="token keyword">let</span> tmp <span class="token operator">=</span> i<span class="token punctuation">;</span>
        chrInt <span class="token operator">=</span> chrInt<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>
            <span class="token parameter">d</span><span class="token operator">=></span><span class="token keyword">this</span><span class="token punctuation">.</span>interceptor<span class="token punctuation">.</span>resInterceptor<span class="token punctuation">[</span>tmp<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">(</span>d<span class="token punctuation">)</span><span class="token punctuation">,</span>
            <span class="token parameter">e</span><span class="token operator">=></span><span class="token keyword">this</span><span class="token punctuation">.</span>interceptor<span class="token punctuation">.</span>resInterceptor<span class="token punctuation">[</span>tmp<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span>
        <span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
    <span class="token keyword">return</span> chrInt<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>

<span class="token comment">// 添加一个请求拦截器，实际上就是加入两个回调函数</span>
<span class="token class-name">Axios</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">addReqInt</span><span class="token operator">=</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">reslv<span class="token punctuation">,</span>rejct</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>interceptor<span class="token punctuation">.</span>reqInterceptor<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">[</span>reslv<span class="token punctuation">,</span>rejct<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>

<span class="token class-name">Axios</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">addResInt</span><span class="token operator">=</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">reslv<span class="token punctuation">,</span>rejct</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>interceptor<span class="token punctuation">.</span>resInterceptor<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">[</span>reslv<span class="token punctuation">,</span>rejct<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>

<span class="token comment">// 请求函数</span>
<span class="token class-name">Axios</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">request</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">config</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    <span class="token comment">// 合并配置文件，注意，这里必须在这里合并，并且不能合并到this.reqconfig否则同时进行多个axios的时候会出现下一个覆盖上一个配置</span>
    <span class="token comment">// 注意绑定顺序</span>
    config <span class="token operator">=</span> config<span class="token operator">||</span><span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
    config <span class="token operator">=</span> utiles<span class="token punctuation">.</span><span class="token function">mergeConfig</span><span class="token punctuation">(</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>defaultConfig<span class="token punctuation">,</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>ReqConfig<span class="token punctuation">,</span>
        config<span class="token punctuation">,</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>methodDefaultConfig<span class="token punctuation">[</span>config<span class="token punctuation">[</span><span class="token string">"method"</span><span class="token punctuation">]</span><span class="token punctuation">]</span>
    <span class="token punctuation">)</span><span class="token punctuation">;</span>
    
    <span class="token comment">// 返回一个Promise链</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">reqinterceptorChain</span><span class="token punctuation">(</span>Promise<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span>config<span class="token punctuation">)</span><span class="token punctuation">)</span>        <span class="token comment">// 请求拦截器</span>
    <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">d</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
        <span class="token comment">// 请求拦截器获得reject不执行</span>
        <span class="token comment">// 正式发请求，这里为了测试在config中加入了want字段，want=true获得200,=false获得404</span>
        <span class="token comment">// 相当于省略了实际的 config解析处理 dispatchRequest.js 响应码的判断 </span>
        <span class="token keyword">if</span><span class="token punctuation">(</span>config<span class="token punctuation">.</span>want<span class="token operator">||</span>Math<span class="token punctuation">.</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">></span><span class="token number">0.5</span><span class="token punctuation">)</span>
            <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span>
                <span class="token string-property property">"statCode"</span><span class="token operator">:</span> <span class="token number">200</span><span class="token punctuation">,</span>
                <span class="token string-property property">"data"</span><span class="token operator">:</span><span class="token string">"假装我是一个响应结果, 方法是"</span><span class="token operator">+</span>config<span class="token punctuation">.</span>method
            <span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
        <span class="token keyword">else</span>
            <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span>
                <span class="token string-property property">"statCode"</span><span class="token operator">:</span> <span class="token number">404</span><span class="token punctuation">,</span>
                <span class="token string-property property">"data"</span><span class="token operator">:</span><span class="token string">"假装我是一个错误, 方法是"</span><span class="token operator">+</span>config<span class="token punctuation">.</span>method
            <span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
    <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>
        <span class="token comment">// 拦截器resolve &amp;&amp; 请求到了200</span>
        <span class="token parameter">d</span><span class="token operator">=></span><span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">resinterceptorChain</span><span class="token punctuation">(</span>Promise<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span>d<span class="token punctuation">)</span><span class="token punctuation">)</span>
    <span class="token punctuation">)</span>
    <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span>
        <span class="token comment">// 请求拦截器reject || 请求到了404</span>
        <span class="token parameter">e</span><span class="token operator">=></span><span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">resinterceptorChain</span><span class="token punctuation">(</span>Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">)</span>
    <span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span>

<span class="token comment">// 为配置文件增加method</span>
<span class="token class-name">Axios</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">get</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">config</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    config <span class="token operator">=</span> config <span class="token operator">||</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
    config<span class="token punctuation">[</span><span class="token string">"method"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"GET"</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">request</span><span class="token punctuation">(</span>config<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span>

<span class="token class-name">Axios</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">post</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">config</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    config <span class="token operator">=</span> <span class="token punctuation">(</span>config <span class="token operator">||</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    config<span class="token punctuation">[</span><span class="token string">"method"</span><span class="token punctuation">]</span> <span class="token operator">=</span>  <span class="token string">"POST"</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">request</span><span class="token punctuation">(</span>config<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span>

<span class="token class-name">Axios</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">put</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">config</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    config <span class="token operator">=</span> <span class="token punctuation">(</span>config <span class="token operator">||</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    config<span class="token punctuation">[</span><span class="token string">"method"</span><span class="token punctuation">]</span> <span class="token operator">=</span>  <span class="token string">"PUT"</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">request</span><span class="token punctuation">(</span>config<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span>

<span class="token class-name">Axios</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">delete</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">config</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    config <span class="token operator">=</span> <span class="token punctuation">(</span>config <span class="token operator">||</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    config<span class="token punctuation">[</span><span class="token string">"method"</span><span class="token punctuation">]</span> <span class="token operator">=</span>  <span class="token string">"DELETE"</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">request</span><span class="token punctuation">(</span>config<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span>

<span class="token comment">// 封装axios</span>

<span class="token keyword">function</span> <span class="token function">buildInstance</span><span class="token punctuation">(</span><span class="token parameter">config</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
    config <span class="token operator">=</span> config<span class="token operator">||</span><span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
    <span class="token keyword">let</span> context <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Axios</span><span class="token punctuation">(</span>config<span class="token punctuation">)</span><span class="token punctuation">;</span>                            <span class="token comment">// 先做一个Axios实例context出来</span>
    <span class="token keyword">let</span> instance<span class="token operator">=</span> <span class="token class-name">Axios</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function">request</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token comment">// 把instance直接绑为context.request 实现 axios(config) 现在他只是函数, 不能执行axios.get()</span>
    <span class="token punctuation">[</span><span class="token string">'get'</span><span class="token punctuation">,</span><span class="token string">'post'</span><span class="token punctuation">,</span><span class="token string">'put'</span><span class="token punctuation">,</span><span class="token string">'delete'</span><span class="token punctuation">,</span><span class="token string">'addReqInt'</span><span class="token punctuation">,</span><span class="token string">'addResInt'</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">d<span class="token punctuation">,</span>i</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>      <span class="token comment">// 实现axios.get()... 但是不能axios.creat()</span>
        instance<span class="token punctuation">[</span>d<span class="token punctuation">]</span><span class="token operator">=</span><span class="token class-name">Axios</span><span class="token punctuation">.</span>prototype<span class="token punctuation">[</span>d<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
    Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">d<span class="token punctuation">,</span>i</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>                       <span class="token comment">// 绑定context的对象，例如拦截器列表</span>
        instance<span class="token punctuation">[</span>d<span class="token punctuation">]</span><span class="token operator">=</span>context<span class="token punctuation">[</span>d<span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
    <span class="token keyword">return</span> instance<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>

<span class="token keyword">let</span> axios <span class="token operator">=</span> <span class="token function">buildInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>                                    <span class="token comment">// axios是一个没有config的实例</span>
axios<span class="token punctuation">.</span>Axios <span class="token operator">=</span> Axios<span class="token punctuation">;</span>
axios<span class="token punctuation">.</span>creat <span class="token operator">=</span> buildInstance<span class="token punctuation">;</span>                                    <span class="token comment">// 绑定creat</span>
<span class="token comment">// 这里还应该绑一些Axios没有但是axios有的</span>

<span class="token comment">// 创建实例duanzi</span>

<span class="token keyword">let</span> duanzi <span class="token operator">=</span> axios<span class="token punctuation">.</span><span class="token function">creat</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span>
    <span class="token string-property property">"type"</span><span class="token operator">:</span> <span class="token string">"duanzi"</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

<span class="token comment">// 加入拦截器</span>
<span class="token comment">// 如果想让请求拦截器给一个reject,修改往下数3,4行</span>
duanzi<span class="token punctuation">.</span><span class="token function">addReqInt</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">d</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"请求拦截器 3 进入成功回调"</span><span class="token punctuation">,</span>d<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> d<span class="token punctuation">;</span>
    <span class="token comment">// return Promise.reject("我是最后一个请求拦截器，我故意挂你的");</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"请求拦截器 3 进入失败回调"</span><span class="token punctuation">,</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> e<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

duanzi<span class="token punctuation">.</span><span class="token function">addReqInt</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">d</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"请求拦截器 2 进入成功回调"</span><span class="token punctuation">,</span>d<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span>d<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"请求拦截器 2 进入失败回调"</span><span class="token punctuation">,</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> e<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

duanzi<span class="token punctuation">.</span><span class="token function">addReqInt</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">d</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"请求拦截器 1 进入成功回调"</span><span class="token punctuation">,</span>d<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span>d<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"请求拦截器 1 进入失败回调"</span><span class="token punctuation">,</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> e<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

duanzi<span class="token punctuation">.</span><span class="token function">addResInt</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">d</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"响应拦截器 1 进入成功回调"</span><span class="token punctuation">,</span>d<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span>d<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"响应拦截器 1 进入失败回调"</span><span class="token punctuation">,</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> e<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

duanzi<span class="token punctuation">.</span><span class="token function">addResInt</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">d</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"响应拦截器 2 进入成功回调"</span><span class="token punctuation">,</span>d<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span>d<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"响应拦截器 2 进入失败回调"</span><span class="token punctuation">,</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> e<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

duanzi<span class="token punctuation">.</span><span class="token function">addResInt</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">d</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"响应拦截器 3 进入成功回调"</span><span class="token punctuation">,</span>d<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> d<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"响应拦截器 3 进入失败回调"</span><span class="token punctuation">,</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 使用实例</span>
<span class="token function">duanzi</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span>
    <span class="token string-property property">"want"</span><span class="token operator">:</span><span class="token boolean">false</span><span class="token punctuation">,</span>
    <span class="token string-property property">"flag"</span><span class="token operator">:</span><span class="token string">"A"</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">d</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Success"</span><span class="token punctuation">,</span>d<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Error"</span><span class="token punctuation">,</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

duanzi<span class="token punctuation">.</span><span class="token function">post</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span>
    <span class="token string-property property">"want"</span><span class="token operator">:</span><span class="token boolean">false</span><span class="token punctuation">,</span>
    <span class="token string-property property">"flag"</span><span class="token operator">:</span><span class="token string">"B"</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">d</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Success"</span><span class="token punctuation">,</span>d<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Error"</span><span class="token punctuation">,</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

<span class="token comment">// 使用axios</span>
<span class="token function">axios</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span>
    <span class="token literal-property property">method</span><span class="token operator">:</span> <span class="token string">"我看看能不能这么写"</span><span class="token punctuation">,</span>
    <span class="token literal-property property">want</span><span class="token operator">:</span> <span class="token boolean">true</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">d</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"*Success"</span><span class="token punctuation">,</span>d<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"*Error"</span><span class="token punctuation">,</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>

axios<span class="token punctuation">.</span><span class="token function">delete</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span>
    <span class="token literal-property property">want</span><span class="token operator">:</span> <span class="token boolean">true</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">d</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"*Success"</span><span class="token punctuation">,</span>d<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"*Error"</span><span class="token punctuation">,</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span></code></pre>
<h3 id="请求发送函数">请求发送函数</h3>
<p>文件在./lib/core/dispatchRequest.js <pre class="language-js" data-language="js"><code class="language-js"><span class="token string">'use strict'</span><span class="token punctuation">;</span>                         <span class="token comment">// 严格模式</span>

<span class="token keyword">var</span> utils <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'./../utils'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">// 工具函数</span>
<span class="token keyword">var</span> transformData <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'./transformData'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token comment">// 转JSON</span>
<span class="token keyword">var</span> isCancel <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'../cancel/isCancel'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>     <span class="token comment">// 取消判定</span>
<span class="token keyword">var</span> defaults <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'../defaults'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>            <span class="token comment">// 默认配置</span>

<span class="token comment">/**
 * 取消
 */</span>
<span class="token keyword">function</span> <span class="token function">throwIfCancellationRequested</span><span class="token punctuation">(</span><span class="token parameter">config</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>config<span class="token punctuation">.</span>cancelToken<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    config<span class="token punctuation">.</span>cancelToken<span class="token punctuation">.</span><span class="token function">throwIfRequested</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>

<span class="token comment">/**
 * 请求发送函数
 *
 * @param &#123;object&#125; config 配置文件
 * @returns &#123;Promise&#125; 返回结果Promise
 */</span>
module<span class="token punctuation">.</span><span class="token function-variable function">exports</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token function">dispatchRequest</span><span class="token punctuation">(</span><span class="token parameter">config</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
  <span class="token function">throwIfCancellationRequested</span><span class="token punctuation">(</span>config<span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">// 配置请求头</span>
  config<span class="token punctuation">.</span>headers <span class="token operator">=</span> config<span class="token punctuation">.</span>headers <span class="token operator">||</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span>

  <span class="token comment">// 数据转换</span>
  config<span class="token punctuation">.</span>data <span class="token operator">=</span> <span class="token function">transformData</span><span class="token punctuation">(</span>
    config<span class="token punctuation">.</span>data<span class="token punctuation">,</span>
    config<span class="token punctuation">.</span>headers<span class="token punctuation">,</span>
    config<span class="token punctuation">.</span>transformRequest
  <span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">// 配置头</span>
  config<span class="token punctuation">.</span>headers <span class="token operator">=</span> utils<span class="token punctuation">.</span><span class="token function">merge</span><span class="token punctuation">(</span>
    config<span class="token punctuation">.</span>headers<span class="token punctuation">.</span>common <span class="token operator">||</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
    config<span class="token punctuation">.</span>headers<span class="token punctuation">[</span>config<span class="token punctuation">.</span>method<span class="token punctuation">]</span> <span class="token operator">||</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
    config<span class="token punctuation">.</span>headers
  <span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">// 配置对应协议必须的请求头</span>
  utils<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span>
    <span class="token punctuation">[</span><span class="token string">'delete'</span><span class="token punctuation">,</span> <span class="token string">'get'</span><span class="token punctuation">,</span> <span class="token string">'head'</span><span class="token punctuation">,</span> <span class="token string">'post'</span><span class="token punctuation">,</span> <span class="token string">'put'</span><span class="token punctuation">,</span> <span class="token string">'patch'</span><span class="token punctuation">,</span> <span class="token string">'common'</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
    <span class="token keyword">function</span> <span class="token function">cleanHeaderConfig</span><span class="token punctuation">(</span><span class="token parameter">method</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
      <span class="token keyword">delete</span> config<span class="token punctuation">.</span>headers<span class="token punctuation">[</span>method<span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
  <span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">// 选择请求器是xhr还是http,也接受用户配置</span>
  <span class="token keyword">var</span> adapter <span class="token operator">=</span> config<span class="token punctuation">.</span>adapter <span class="token operator">||</span> defaults<span class="token punctuation">.</span>adapter<span class="token punctuation">;</span>

  <span class="token comment">// 调用xhr/http获得结果，转换结果，返回resolve/reject</span>
  <span class="token keyword">return</span> <span class="token function">adapter</span><span class="token punctuation">(</span>config<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token function">onAdapterResolution</span><span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    <span class="token function">throwIfCancellationRequested</span><span class="token punctuation">(</span>config<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token comment">// Transform response data</span>
    response<span class="token punctuation">.</span>data <span class="token operator">=</span> <span class="token function">transformData</span><span class="token punctuation">(</span>
      response<span class="token punctuation">.</span>data<span class="token punctuation">,</span>
      response<span class="token punctuation">.</span>headers<span class="token punctuation">,</span>
      config<span class="token punctuation">.</span>transformResponse
    <span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">return</span> response<span class="token punctuation">;</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token function">onAdapterRejection</span><span class="token punctuation">(</span><span class="token parameter">reason</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">isCancel</span><span class="token punctuation">(</span>reason<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
      <span class="token function">throwIfCancellationRequested</span><span class="token punctuation">(</span>config<span class="token punctuation">)</span><span class="token punctuation">;</span>

      <span class="token comment">// Transform response data</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span>reason <span class="token operator">&amp;&amp;</span> reason<span class="token punctuation">.</span>response<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        reason<span class="token punctuation">.</span>response<span class="token punctuation">.</span>data <span class="token operator">=</span> <span class="token function">transformData</span><span class="token punctuation">(</span>
          reason<span class="token punctuation">.</span>response<span class="token punctuation">.</span>data<span class="token punctuation">,</span>
          reason<span class="token punctuation">.</span>response<span class="token punctuation">.</span>headers<span class="token punctuation">,</span>
          config<span class="token punctuation">.</span>transformResponse
        <span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token punctuation">&#125;</span>
    <span class="token punctuation">&#125;</span>

    <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span>reason<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span></code></pre></p>
<h3 id="请求取消函数">请求取消函数</h3>
<p>前端操作代码 <pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> cancelFlag <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
btn_req<span class="token punctuation">.</span><span class="token function-variable function">onclick</span><span class="token operator">=</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
  <span class="token function">axios</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span>
    <span class="token literal-property property">method</span>  <span class="token operator">:</span>   <span class="token string">"GET"</span><span class="token punctuation">,</span>
    <span class="token literal-property property">url</span>     <span class="token operator">:</span>   <span class="token string">"http://127.0.0.1:3000/posts"</span><span class="token punctuation">,</span>
    <span class="token literal-property property">cancelToken</span><span class="token operator">:</span> <span class="token keyword">new</span> <span class="token class-name">axios<span class="token punctuation">.</span>CancelToken</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">c</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
      cancelFlag <span class="token operator">=</span> c<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"OK"</span><span class="token punctuation">)</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span>

btn_can<span class="token punctuation">.</span><span class="token function-variable function">onclick</span><span class="token operator">=</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
  <span class="token function">cancelFlag</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Cancel"</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span></code></pre></p>
<p>Cancel对象(./lib/cancel/CancelToken.js) <pre class="language-js" data-language="js"><code class="language-js"><span class="token comment">/**
 * A `CancelToken` is an object that can be used to request cancellation of an operation.
 *
 * @class
 * @param &#123;Function&#125; executor The executor function.
 */</span>
<span class="token keyword">function</span> <span class="token function">CancelToken</span><span class="token punctuation">(</span><span class="token parameter">executor</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> executor <span class="token operator">!==</span> <span class="token string">'function'</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">TypeError</span><span class="token punctuation">(</span><span class="token string">'executor must be a function.'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">&#125;</span>

  <span class="token keyword">var</span> resolvePromise<span class="token punctuation">;</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span>promise <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token function">promiseExecutor</span><span class="token punctuation">(</span><span class="token parameter">resolve</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    resolvePromise <span class="token operator">=</span> resolve<span class="token punctuation">;</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">var</span> token <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">;</span>
  <span class="token function">executor</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token function">cancel</span><span class="token punctuation">(</span><span class="token parameter">message</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>token<span class="token punctuation">.</span>reason<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
      <span class="token comment">// Cancellation has already been requested</span>
      <span class="token keyword">return</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

    token<span class="token punctuation">.</span>reason <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Cancel</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">resolvePromise</span><span class="token punctuation">(</span>token<span class="token punctuation">.</span>reason<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span></code></pre></p>
<p>xhr适配器158-170行(./lib/adapters/xhr.js) <pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">if</span> <span class="token punctuation">(</span>config<span class="token punctuation">.</span>cancelToken<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
  <span class="token comment">// Handle cancellation</span>
  config<span class="token punctuation">.</span>cancelToken<span class="token punctuation">.</span>promise<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token function">onCanceled</span><span class="token punctuation">(</span><span class="token parameter">cancel</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>request<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
      <span class="token keyword">return</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

    request<span class="token punctuation">.</span><span class="token function">abort</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">reject</span><span class="token punctuation">(</span>cancel<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// Clean up request</span>
    request <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span></code></pre></p>
<p>首先在前端发送请求的时候需要配置 <pre class="language-js" data-language="js"><code class="language-js"><span class="token literal-property property">cancelToken</span><span class="token operator">:</span> <span class="token keyword">new</span> <span class="token class-name">axios<span class="token punctuation">.</span>CancelToken</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">c</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
  cancelFlag <span class="token operator">=</span> c<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span></code></pre></p>
<p>相当于在创建请求的时候创建了一个CancelTocken对象，<strong>保存在config</strong></p>
<p>构造函数如下 <pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">CancelToken</span><span class="token punctuation">(</span><span class="token parameter">executor</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
  <span class="token comment">// 如果没有传入一个函数直接报错</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> executor <span class="token operator">!==</span> <span class="token string">'function'</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">TypeError</span><span class="token punctuation">(</span><span class="token string">'executor must be a function.'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">&#125;</span>

  <span class="token comment">// 定义一个resolvePromise变量</span>
  <span class="token keyword">var</span> resolvePromise<span class="token punctuation">;</span>

  <span class="token comment">// 对象具有一个promise，默认下是padding因为里面的函数没有返回</span>
  <span class="token comment">// promise会resolve当且仅当resolve也就是resolvePromise被执行</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span>promise <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token function">promiseExecutor</span><span class="token punctuation">(</span><span class="token parameter">resolve</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    resolvePromise <span class="token operator">=</span> resolve<span class="token punctuation">;</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">var</span> token <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">;</span>                 <span class="token comment">// 拷贝this传入闭包</span>
  <span class="token comment">// executor是传入的函数，我们要执行这个传入的函数，并且这个传入函数的参数是一个函数</span>
  <span class="token comment">// 从前端看就是cancel被赋值成了这个函数function cancel(message)</span>
  <span class="token function">executor</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token function">cancel</span><span class="token punctuation">(</span><span class="token parameter">message</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    <span class="token comment">// 如果reason存在就直接返回</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>token<span class="token punctuation">.</span>reason<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
      <span class="token comment">// Cancellation has already been requested</span>
      <span class="token keyword">return</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
    <span class="token comment">// 否则构建一个新tocken</span>
    token<span class="token punctuation">.</span>reason <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Cancel</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// 执行这个函数，就是将promise变成resolve</span>
    <span class="token function">resolvePromise</span><span class="token punctuation">(</span>token<span class="token punctuation">.</span>reason<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span></code></pre></p>
<p>我们看下promise变成resolve之后发生什么，在xhr.js中，在初始化的时候有一段代码
<pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">if</span> <span class="token punctuation">(</span>config<span class="token punctuation">.</span>cancelToken<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
  <span class="token comment">// Handle cancellation</span>
  config<span class="token punctuation">.</span>cancelToken<span class="token punctuation">.</span>promise<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token function">onCanceled</span><span class="token punctuation">(</span><span class="token parameter">cancel</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>request<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
      <span class="token keyword">return</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

    request<span class="token punctuation">.</span><span class="token function">abort</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">reject</span><span class="token punctuation">(</span>cancel<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// Clean up request</span>
    request <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span></code></pre>
如果定义了cancelToken那么设置promise的then，如果没有请求就返回，请求了就abort请求，返回reject,同时设置请求为null</p>
<p>这样做虽然有点绕，但是实现了 -
Axios将promise.resolve()通过构造函数的回调函数传递给了前端 -
Axios将底层取消的代码通过config放在了适配器的js文件中 - 代码的分离</p>
<p>模式是:</p>
<p>构造函数 <pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">cancelTocken</span><span class="token punctuation">(</span><span class="token parameter">executor</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
  <span class="token comment">// 判定前端是否传递了回调函数用于取消</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> executor <span class="token operator">!==</span> <span class="token string">'function'</span><span class="token punctuation">)</span>
    <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">TypeError</span><span class="token punctuation">(</span><span class="token string">'executor must be a function.'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">var</span> resolvePromise<span class="token punctuation">;</span>               <span class="token comment">// 暴露resolve函数</span>

  <span class="token keyword">this</span><span class="token punctuation">.</span>promise <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token function">promiseExecutor</span><span class="token punctuation">(</span><span class="token parameter">resolve</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    resolvePromise <span class="token operator">=</span> resolve<span class="token punctuation">;</span>       <span class="token comment">// 放置Promise，将resolve给暴露变量</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">// 前端赋值的结果</span>
  <span class="token function">executor</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">message</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    <span class="token function">resolvePromise</span><span class="token punctuation">(</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span></code></pre></p>
<p>前端调用 <pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">let</span> cancel <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> ct <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">cancelTocken</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">d</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>cancel <span class="token operator">=</span> d<span class="token punctuation">;</span><span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>xxx<span class="token punctuation">)</span>
  <span class="token function">cancel</span><span class="token punctuation">(</span><span class="token string">"加入你想传递一些信息"</span><span class="token punctuation">)</span></code></pre></p>
<p>底层代码 <pre class="language-js" data-language="js"><code class="language-js"><span class="token keyword">if</span><span class="token punctuation">(</span>存在这么个promise<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
  这个promise<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">d</span><span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">&#123;</span>
    <span class="token comment">// 传递的信息就到d变量了</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span></code></pre></p>
<h3 id="总结八股">总结(八股)</h3>
<ul>
<li>Axios与axios的关系
<ul>
<li>axios不是Axios实例</li>
<li>axios拥有Axios实例的全部方法</li>
<li>axios绑定了Axios.request</li>
<li>axios还扩展了creat()的结果</li>
</ul></li>
<li>instance和axios的区别
<ul>
<li>instance是Axios实例+request</li>
<li>axios在instance上扩展了creat,Axios,isCancel...方法</li>
</ul></li>
<li>axios的整体流程</li>
</ul>
<pre class="mermaid">graph TB
axios.creat --> creatInstance
axios --> creatInstance
creatInstance --> 执行别名
config --> 执行别名
执行别名 --> axios.prototype.request
axios.prototype.request --> request.Interceptors
request.Interceptors --> adapter
adapter --> cancel
cancel --yes--> axios.reject
cancel --no--> axios.fulfiled
responseInterceptor --> axios.then/catch
cancel --> responseInterceptor</pre>
<ul>
<li>拦截器是什么
<ul>
<li>在发送与响应前后的函数</li>
<li>请求拦截器传送config</li>
<li>响应拦截器传送response</li>
</ul></li>
<li>请求转换器的作用
<ul>
<li>完全可以由拦截器做</li>
<li>对config/response进行预处理</li>
</ul></li>
</ul>

    </div>

    
    
    
      


    <footer class="post-footer">
          <div class="reward-container">
  <div></div>
  <button>
    赞赏
  </button>
  <div class="post-reward">
      <div>
        <img src="/images/wechatpay.png" alt="Liu Kairui 微信">
        <span>微信</span>
      </div>
      <div>
        <img src="/images/alipay.png" alt="Liu Kairui 支付宝">
        <span>支付宝</span>
      </div>

  </div>
</div>

          

<div class="post-copyright">
<ul>
  <li class="post-copyright-author">
      <strong>本文作者： </strong>Liu Kairui
  </li>
  <li class="post-copyright-link">
      <strong>本文链接：</strong>
      <a href="http://liukairui.me/article/Ajax%E4%B8%8EAxios%E7%9A%84%E4%BD%BF%E7%94%A8%E4%B8%8E%E5%85%B3%E9%94%AE%E6%BA%90%E7%A0%81%E7%AC%94%E8%AE%B0/" title="Ajax与Axios的使用与关键源码笔记">http://liukairui.me/article/Ajax与Axios的使用与关键源码笔记/</a>
  </li>
  <li class="post-copyright-license">
    <strong>版权声明： </strong>本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh" rel="noopener" target="_blank"><i class="fab fa-fw fa-creative-commons"></i>BY-NC-SA</a> 许可协议。转载请注明出处！
  </li>
</ul>
</div>

          <div class="post-tags">
              <a href="/tags/%E5%89%8D%E7%AB%AF/" rel="tag"><i class="fa fa-tag"></i> 前端</a>
              <a href="/tags/%E7%AC%94%E8%AE%B0/" rel="tag"><i class="fa fa-tag"></i> 笔记</a>
              <a href="/tags/JavaScript/" rel="tag"><i class="fa fa-tag"></i> JavaScript</a>
              <a href="/tags/Ajax/" rel="tag"><i class="fa fa-tag"></i> Ajax</a>
              <a href="/tags/Axios/" rel="tag"><i class="fa fa-tag"></i> Axios</a>
          </div>

        

          <div class="post-nav">
            <div class="post-nav-item">
                <a href="/article/Node.js%E8%B5%B7%E6%AD%A5%E7%AC%94%E8%AE%B0/" rel="prev" title="Node.js起步笔记">
                  <i class="fa fa-chevron-left"></i> Node.js起步笔记
                </a>
            </div>
            <div class="post-nav-item">
                <a href="/article/ES6-12%E4%B8%8E%E6%A8%A1%E5%9D%97%E5%8C%96%E7%AC%94%E8%AE%B0/" rel="next" title="ES6-12与JS模块化笔记">
                  ES6-12与JS模块化笔记 <i class="fa fa-chevron-right"></i>
                </a>
            </div>
          </div>
    </footer>
  </article>
</div>






    <div class="comments" id="valine-comments"></div>
</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">


<div class="copyright">
  &copy; 2019 – 
  <span itemprop="copyrightYear">2022</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Liu Kairui</span>
</div>
<div class="busuanzi-count">
    <span class="post-meta-item" id="busuanzi_container_site_uv">
      <span class="post-meta-item-icon">
        <i class="fa fa-user"></i>
      </span>
      <span class="site-uv" title="总访客量">
        <span id="busuanzi_value_site_uv"></span>
      </span>
    </span>
    <span class="post-meta-item" id="busuanzi_container_site_pv">
      <span class="post-meta-item-icon">
        <i class="fa fa-eye"></i>
      </span>
      <span class="site-pv" title="总访问量">
        <span id="busuanzi_value_site_pv"></span>
      </span>
    </span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/muse/" rel="noopener" target="_blank">NexT.Muse</a> 强力驱动
  </div>
  <div class="addthis_inline_share_toolbox">
    <script src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-6231eb6f709fc868" async="async"></script>
  </div><script
  async
  src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"
></script>

 
<script src="https://cdn.jsdelivr.net/npm/moment@2.22.2/moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/moment-precise-range-plugin@1.3.0/moment-precise-range.min.js"></script>
<script>
  function timer() {
    var ages = moment.preciseDiff(moment(),moment(20201101,"YYYYMMDD"));
    ages = ages.replace(/years?/, "年");
    ages = ages.replace(/months?/, "月");
    ages = ages.replace(/days?/, "天");
    ages = ages.replace(/hours?/, "小时");
    ages = ages.replace(/minutes?/, "分");
    ages = ages.replace(/seconds?/, "秒");
    ages = ages.replace(/\d+/g, '<span class="daysCnt" style="color:#1890ff">$&</span>');
    div.innerHTML = `我已在此等候你 ${ages}`;
    div.className="workDays";
  }
  var div = document.createElement("div");
  //插入到copyright之后
  var copyright = document.querySelector(".copyright");
  document.querySelector(".footer-inner").insertBefore(div, copyright.nextSibling);
  timer();
  setInterval("timer()",1000)
</script>



    </div>
  </footer>

  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/@next-theme/pjax@0.5.0/pjax.min.js" integrity="sha256-3NkoLDrmHLTYj7csHIZSr0MHAFTXth7Ua/DDt4MRUAg=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.js" integrity="sha256-yt2kYMy0w8AbtF89WXb2P1rfjcP/HTHLT7097U8Y5b8=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/lozad.js/1.16.0/lozad.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/pangu/4.0.7/pangu.min.js"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/schemes/muse.js"></script><script src="/js/next-boot.js"></script><script src="/js/pjax.js"></script>

  
<script src="https://cdn.jsdelivr.net/npm/hexo-generator-searchdb@1.4.0/dist/search.js" integrity="sha256-vXZMYLEqsROAXkEw93GGIvaB2ab+QW6w3+1ahD9nXXA=" crossorigin="anonymous"></script>
<script src="/js/third-party/search/local-search.js"></script>


  <script class="next-config" data-name="mermaid" type="application/json">{"enable":true,"theme":"forest","js":{"url":"https://cdnjs.cloudflare.com/ajax/libs/mermaid/8.14.0/mermaid.min.js","integrity":"sha256-7wT34TI0pEBeEFoi4z+vhuSddGh6vUTMWdqJ2SDe2jg="}}</script>
  <script src="/js/third-party/tags/mermaid.js"></script>

  <script src="/js/third-party/fancybox.js"></script>

  <script src="/js/third-party/pace.js"></script>

  
  <script data-pjax async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>


  <script class="next-config" data-name="leancloud_visitors" type="application/json">{"enable":true,"app_id":"ABKlVtS4cyaWYEwunPyK3sXt-9Nh9j0Va","app_key":"xxGXdTTEGEVifs2TLB35844I","server_url":"https://abklvts4.lc-cn-e1-shared.com","security":false}</script>
  <script src="/js/third-party/statistics/lean-analytics.js"></script>


  

  <script class="next-config" data-name="enableMath" type="application/json">true</script><script class="next-config" data-name="mathjax" type="application/json">{"enable":true,"tags":"none","mhchem":true,"js":{"url":"https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.0/es5/tex-mml-chtml.min.js"}}</script>
<script src="/js/third-party/math/mathjax.js"></script>


  <script src="https://cdnjs.cloudflare.com/ajax/libs/quicklink/2.2.0/quicklink.umd.js" integrity="sha256-4kQf9z5ntdQrzsBC3YSHnEz02Z9C1UeW/E9OgnvlzSY=" crossorigin="anonymous"></script>
  <script class="next-config" data-name="quicklink" type="application/json">{"enable":true,"home":false,"archive":false,"delay":true,"timeout":3000,"priority":true,"url":"http://liukairui.me/article/Ajax%E4%B8%8EAxios%E7%9A%84%E4%BD%BF%E7%94%A8%E4%B8%8E%E5%85%B3%E9%94%AE%E6%BA%90%E7%A0%81%E7%AC%94%E8%AE%B0/"}</script>
  <script src="/js/third-party/quicklink.js"></script>
<script src="https://cdn.jsdelivr.net/npm/darkmode-js@1.5.7/lib/darkmode-js.min.js"></script>

<script>
var options = {
  bottom: '64px',
  right: 'unset',
  left: '32px',
  time: '0.5s',
  mixColor: 'transparent',
  backgroundColor: 'transparent',
  buttonColorDark: '#100f2c',
  buttonColorLight: '#fff',
  saveInCookies: true,
  label: '🌓',
  autoMatchOsTheme: true
}
const darkmode = new Darkmode(options);
window.darkmode = darkmode;
darkmode.showWidget();
</script>


<script class="next-config" data-name="valine" type="application/json">{"enable":true,"appId":"ABKlVtS4cyaWYEwunPyK3sXt-9Nh9j0Va","appKey":"xxGXdTTEGEVifs2TLB35844I","serverURLs":"https://abklvts4.lc-cn-e1-shared.com","placeholder":"请开始你的表演","avatar":"identicon","meta":["nick","mail","link"],"pageSize":10,"lang":"zh-CN","visitor":false,"comment_count":true,"recordIP":true,"enableQQ":true,"requiredFields":[],"el":"#valine-comments","path":"/article/Ajax%E4%B8%8EAxios%E7%9A%84%E4%BD%BF%E7%94%A8%E4%B8%8E%E5%85%B3%E9%94%AE%E6%BA%90%E7%A0%81%E7%AC%94%E8%AE%B0/"}</script>
<script>
document.addEventListener('page:loaded', () => {
  NexT.utils.loadComments(CONFIG.valine.el)
    .then(() => NexT.utils.getScript(
      'https://cdn.jsdelivr.net/npm/valine@1.4.14/dist/Valine.min.js',
      { condition: window.Valine }
    ))
    .then(() => {
      new Valine(CONFIG.valine);
    });
});
</script>


  <script async src="/js/fireworks.js"></script>




  <script src="/js/activate-power-mode.min.js"></script>
  <script>
    POWERMODE.colorful = true;
    POWERMODE.shake = false;
    document.body.addEventListener('input', POWERMODE);
  </script>




  <script src="/js/wobblewindow.js"></script>
  <script>
    //只在桌面版网页启用特效 记得同步到header.njk
    if( window.innerWidth > 768  ){
      $(document).ready(function () {
        
          $('body>main>header').wobbleWindow({
            radius: 50,
            movementTop: false,
            movementLeft: false,
            movementRight: false,
            debug: false,
          });
        

        //
        //  $('body header>aside').wobbleWindow({
        //    radius: 50,
        //    movementLeft: false,
        //    movementTop: false,
        //    movementBottom: false,
        //    position: 'fixed',
        //    debug: false,
        //  });
        //

        
          $('body>footer').wobbleWindow({
            radius: 50,
            movementBottom: false,
            movementLeft: false,
            movementRight: false,
            debug: false,
          });
        
      });
    }
  </script>


 
<script>
  $(document).ready(function(){
    var beian = document.querySelector(".footer-inner > .beian > a");
    var cpr=document.querySelector(".footer-inner > .copyright");
    var cnz=document.querySelector(".workDays");//.parentNode;
    var bsz=document.querySelector(".busuanzi-count");
    if(cnz!=null&&bsz!=null)
      cnz.parentNode.insertBefore(bsz,cnz);
    if(bsz == null || bsz == undefined || document.querySelector("#busuanzi_value_site_pv").innerText=="" || document.querySelector("#busuanzi_value_site_uv").innerText == "")
      bsz.remove();
    checkIndex();
    if(beian){cpr.classList.add('split-line');cpr.appendChild(beian);}
  })
  $(document).on('pjax:complete',checkIndex);
</script>



<script src="/live2dw/lib/L2Dwidget.min.js?094cbace49a39548bed64abff5988b05"></script><script>L2Dwidget.init({"pluginRootPath":"live2dw/","pluginJsPath":"lib/","pluginModelPath":"assets/","tagMode":false,"log":false,"model":{"jsonPath":"/live2dw/assets/hijiki.model.json"},"display":{"position":"right","width":150,"height":300},"mobile":{"show":false},"react":{"opacity":0.7}});</script></body>
</html>
